2 * Routines for decoding isis hello packets and their CLVs
5 * Stuart Stanley <stuarts@mxmail.net>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include <epan/packet.h>
30 #include "packet-osi.h"
31 #include "packet-isis.h"
32 #include "packet-isis-clv.h"
33 #include "packet-isis-hello.h"
34 #include <epan/addr_resolv.h>
37 #define APPEND_BOOLEAN_FLAG(flag, item, string) \
40 proto_item_append_text(item, string, sep); \
43 static const char initial_sep
[] = " (";
44 static const char cont_sep
[] = ", ";
48 static int hf_isis_hello_circuit_reserved
= -1;
49 static int hf_isis_hello_source_id
= -1;
50 static int hf_isis_hello_holding_timer
= -1;
51 static int hf_isis_hello_pdu_length
= -1;
52 static int hf_isis_hello_priority_reserved
= -1;
53 static int hf_isis_hello_lan_id
= -1;
54 static int hf_isis_hello_local_circuit_id
= -1;
55 static int hf_isis_hello_clv_ipv4_int_addr
= -1;
56 static int hf_isis_hello_clv_ipv6_int_addr
= -1;
57 /* static int hf_isis_hello_clv_ptp_adj = -1; */
58 static int hf_isis_hello_clv_mt
= -1;
59 static int hf_isis_hello_clv_restart_flags
= -1;
60 static int hf_isis_hello_clv_restart_flags_rr
= -1;
61 static int hf_isis_hello_clv_restart_flags_ra
= -1;
62 static int hf_isis_hello_clv_restart_flags_sa
= -1;
63 static int hf_isis_hello_clv_restart_remain_time
= -1;
64 static int hf_isis_hello_clv_restart_neighbor
= -1;
66 static gint ett_isis_hello
= -1;
67 static gint ett_isis_hello_clv_area_addr
= -1;
68 static gint ett_isis_hello_clv_is_neighbors
= -1;
69 static gint ett_isis_hello_clv_padding
= -1;
70 static gint ett_isis_hello_clv_unknown
= -1;
71 static gint ett_isis_hello_clv_nlpid
= -1;
72 static gint ett_isis_hello_clv_authentication
= -1;
73 static gint ett_isis_hello_clv_ip_authentication
= -1;
74 static gint ett_isis_hello_clv_ipv4_int_addr
= -1;
75 static gint ett_isis_hello_clv_ipv6_int_addr
= -1;
76 static gint ett_isis_hello_clv_ptp_adj
= -1;
77 static gint ett_isis_hello_clv_mt
= -1;
78 static gint ett_isis_hello_clv_restart
= -1;
79 static gint ett_isis_hello_clv_restart_flags
= -1;
80 static gint ett_isis_hello_clv_mt_port_cap
= -1;
81 static gint ett_isis_hello_clv_mt_port_cap_spb_mcid
= -1;
82 static gint ett_isis_hello_clv_mt_port_cap_spb_aux_mcid
= -1;
83 static gint ett_isis_hello_clv_mt_port_cap_spb_digest
= -1;
84 static gint ett_isis_hello_clv_mt_port_cap_spb_bvid_tuples
= -1;
85 static gint ett_isis_hello_clv_checksum
= -1;
87 static const value_string isis_hello_circuit_type_vals
[] = {
88 { ISIS_HELLO_TYPE_RESERVED
, "Reserved 0 (discard PDU)"},
89 { ISIS_HELLO_TYPE_LEVEL_1
, "Level 1 only"},
90 { ISIS_HELLO_TYPE_LEVEL_2
, "Level 2 only"},
91 { ISIS_HELLO_TYPE_LEVEL_12
, "Level 1 and 2"},
95 * Predclare dissectors for use in clv dissection.
97 static void dissect_hello_padding_clv(tvbuff_t
*tvb
,
98 proto_tree
*tree
, int offset
, int id_length
, int length
);
99 static void dissect_hello_is_neighbors_clv(tvbuff_t
*tvb
,
100 proto_tree
*tree
, int offset
, int id_length
, int length
);
101 static void dissect_hello_ptp_adj_clv(tvbuff_t
*tvb
,
102 proto_tree
*tree
, int offset
, int id_length
, int length
);
103 static void dissect_hello_area_address_clv(tvbuff_t
*tvb
,
104 proto_tree
*tree
, int offset
, int id_length
, int length
);
105 static void dissect_hello_authentication_clv(tvbuff_t
*tvb
,
106 proto_tree
*tree
, int offset
, int id_length
, int length
);
107 static void dissect_hello_ip_authentication_clv(tvbuff_t
*tvb
,
108 proto_tree
*tree
, int offset
, int id_length
, int length
);
109 static void dissect_hello_checksum_clv(tvbuff_t
*tvb
,
110 proto_tree
*tree
, int offset
, int id_length
, int length
);
111 static void dissect_hello_ipv6_int_addr_clv(tvbuff_t
*tvb
,
112 proto_tree
*tree
, int offset
, int id_length
, int length
);
113 static void dissect_hello_ip_int_addr_clv(tvbuff_t
*tvb
,
114 proto_tree
*tree
, int offset
, int id_length
, int length
);
115 static void dissect_hello_mt_clv(tvbuff_t
*tvb
,
116 proto_tree
*tree
, int offset
, int id_length
, int length
);
117 static void dissect_hello_nlpid_clv(tvbuff_t
*tvb
,
118 proto_tree
*tree
, int offset
, int id_length
, int length
);
119 static void dissect_hello_restart_clv(tvbuff_t
*tvb
,
120 proto_tree
*tree
, int offset
, int id_length
, int length
);
121 static void dissect_hello_mt_port_cap_clv(tvbuff_t
*tvb
,
122 proto_tree
*tree
, int offset
, int id_length
, int length
);
125 static const isis_clv_handle_t clv_l1_hello_opts
[] = {
127 ISIS_CLV_AREA_ADDRESS
,
129 &ett_isis_hello_clv_area_addr
,
130 dissect_hello_area_address_clv
133 ISIS_CLV_IS_NEIGHBORS
,
135 &ett_isis_hello_clv_is_neighbors
,
136 dissect_hello_is_neighbors_clv
141 &ett_isis_hello_clv_padding
,
142 dissect_hello_padding_clv
145 ISIS_CLV_PROTOCOLS_SUPPORTED
,
146 "Protocols Supported",
147 &ett_isis_hello_clv_nlpid
,
148 dissect_hello_nlpid_clv
152 "IP Interface address(es)",
153 &ett_isis_hello_clv_ipv4_int_addr
,
154 dissect_hello_ip_int_addr_clv
158 "IPv6 Interface address(es)",
159 &ett_isis_hello_clv_ipv6_int_addr
,
160 dissect_hello_ipv6_int_addr_clv
165 &ett_isis_hello_clv_restart
,
166 dissect_hello_restart_clv
169 ISIS_CLV_AUTHENTICATION
,
171 &ett_isis_hello_clv_authentication
,
172 dissect_hello_authentication_clv
175 ISIS_CLV_IP_AUTHENTICATION
,
177 &ett_isis_hello_clv_ip_authentication
,
178 dissect_hello_ip_authentication_clv
181 ISIS_CLV_MT_SUPPORTED
,
183 &ett_isis_hello_clv_mt
,
189 &ett_isis_hello_clv_checksum
,
190 dissect_hello_checksum_clv
200 static const isis_clv_handle_t clv_l2_hello_opts
[] = {
202 ISIS_CLV_AREA_ADDRESS
,
204 &ett_isis_hello_clv_area_addr
,
205 dissect_hello_area_address_clv
208 ISIS_CLV_IS_NEIGHBORS
,
210 &ett_isis_hello_clv_is_neighbors
,
211 dissect_hello_is_neighbors_clv
216 &ett_isis_hello_clv_padding
,
217 dissect_hello_padding_clv
220 ISIS_CLV_PROTOCOLS_SUPPORTED
,
221 "Protocols Supported",
222 &ett_isis_hello_clv_nlpid
,
223 dissect_hello_nlpid_clv
227 "IP Interface address(es)",
228 &ett_isis_hello_clv_ipv4_int_addr
,
229 dissect_hello_ip_int_addr_clv
233 "IPv6 Interface address(es)",
234 &ett_isis_hello_clv_ipv6_int_addr
,
235 dissect_hello_ipv6_int_addr_clv
238 ISIS_CLV_AUTHENTICATION
,
240 &ett_isis_hello_clv_authentication
,
241 dissect_hello_authentication_clv
244 ISIS_CLV_IP_AUTHENTICATION
,
246 &ett_isis_hello_clv_ip_authentication
,
247 dissect_hello_ip_authentication_clv
252 &ett_isis_hello_clv_restart
,
253 dissect_hello_restart_clv
256 ISIS_CLV_MT_SUPPORTED
,
258 &ett_isis_hello_clv_mt
,
264 &ett_isis_hello_clv_checksum
,
265 dissect_hello_checksum_clv
275 static const isis_clv_handle_t clv_ptp_hello_opts
[] = {
277 ISIS_CLV_AREA_ADDRESS
,
279 &ett_isis_hello_clv_area_addr
,
280 dissect_hello_area_address_clv
285 &ett_isis_hello_clv_padding
,
286 dissect_hello_padding_clv
289 ISIS_CLV_PROTOCOLS_SUPPORTED
,
290 "Protocols Supported",
291 &ett_isis_hello_clv_nlpid
,
292 dissect_hello_nlpid_clv
296 "IP Interface address(es)",
297 &ett_isis_hello_clv_ipv4_int_addr
,
298 dissect_hello_ip_int_addr_clv
302 "IPv6 Interface address(es)",
303 &ett_isis_hello_clv_ipv6_int_addr
,
304 dissect_hello_ipv6_int_addr_clv
307 ISIS_CLV_AUTHENTICATION
,
309 &ett_isis_hello_clv_authentication
,
310 dissect_hello_authentication_clv
313 ISIS_CLV_IP_AUTHENTICATION
,
315 &ett_isis_hello_clv_ip_authentication
,
316 dissect_hello_ip_authentication_clv
319 ISIS_CLV_MT_PORT_CAP
,
320 "MT Port Capability",
321 &ett_isis_hello_clv_mt_port_cap
,
322 dissect_hello_mt_port_cap_clv
327 &ett_isis_hello_clv_restart
,
328 dissect_hello_restart_clv
331 ISIS_CLV_PTP_ADJ_STATE
,
332 "Point-to-point Adjacency State",
333 &ett_isis_hello_clv_ptp_adj
,
334 dissect_hello_ptp_adj_clv
337 ISIS_CLV_MT_SUPPORTED
,
339 &ett_isis_hello_clv_mt
,
345 &ett_isis_hello_clv_checksum
,
346 dissect_hello_checksum_clv
357 dissect_hello_mt_port_cap_spb_mcid_clv(tvbuff_t
*tvb
,
358 proto_tree
*tree
, int offset
, int subtype
, int sublen
)
360 const int MCID_LEN
= 51;
361 const int SUBLEN
= 2 * MCID_LEN
;
363 if (sublen
!= SUBLEN
) {
364 isis_dissect_unknown( tvb
, tree
, offset
,
365 "Short SPB MCID TLV (%d vs %d)", sublen
, SUBLEN
);
369 proto_tree
*subtree
, *ti
;
370 const guint8
*mcid
= tvb_get_ptr(tvb
, offset
, MCID_LEN
);
371 const guint8
*aux_mcid
= tvb_get_ptr(tvb
, offset
+ MCID_LEN
, MCID_LEN
);
374 ti
= proto_tree_add_text( tree
, tvb
, offset
-2, sublen
+2,
375 "SPB MCID: Type: 0x%02x, Length: %d", subtype
, sublen
);
376 subtree
= proto_item_add_subtree(ti
, ett_isis_hello_clv_mt_port_cap_spb_mcid
);
379 proto_tree_add_text( subtree
, tvb
, offset
, MCID_LEN
, "MCID:");
380 for (i
= 0 ; i
< 48 ; i
+= 8, offset
+= 8) {
381 proto_tree_add_text( subtree
, tvb
, offset
, 8,
382 " %02x %02x %02x %02x %02x %02x %02x %02x",
383 mcid
[i
+0], mcid
[i
+1], mcid
[i
+2], mcid
[i
+3],
384 mcid
[i
+4], mcid
[i
+5], mcid
[i
+6], mcid
[i
+7]);
386 proto_tree_add_text( subtree
, tvb
, offset
, 3,
388 mcid
[i
+0], mcid
[i
+1], mcid
[i
+2]);
392 proto_tree_add_text( subtree
, tvb
, offset
, MCID_LEN
, "Aux MCID:");
393 for (i
= 0 ; i
< 48 ; i
+= 8, offset
+= 8) {
394 proto_tree_add_text( subtree
, tvb
, offset
, 8,
395 " %02x %02x %02x %02x %02x %02x %02x %02x",
396 aux_mcid
[i
+0], aux_mcid
[i
+1], aux_mcid
[i
+2], aux_mcid
[i
+3],
397 aux_mcid
[i
+4], aux_mcid
[i
+5], aux_mcid
[i
+6], aux_mcid
[i
+7]);
399 proto_tree_add_text( subtree
, tvb
, offset
, 3,
401 aux_mcid
[i
+0], aux_mcid
[i
+1], aux_mcid
[i
+2]);
407 dissect_hello_mt_port_cap_spb_digest_clv(tvbuff_t
*tvb
,
408 proto_tree
*tree
, int offset
, int subtype
, int sublen
)
410 const int DIGEST_LEN
= 32;
411 const int SUBLEN
= 1 + DIGEST_LEN
;
412 if (sublen
!= SUBLEN
) {
413 isis_dissect_unknown( tvb
, tree
, offset
,
414 "Short SPB Digest TLV (%d vs %d)", sublen
, SUBLEN
);
418 proto_tree
*subtree
, *ti
;
419 const guint8 vad
= tvb_get_guint8(tvb
, offset
);
420 const guint8
*digest
= tvb_get_ptr(tvb
, offset
+ 1, DIGEST_LEN
);
423 ti
= proto_tree_add_text( tree
, tvb
, offset
-2, sublen
+2,
424 "SPB Digest: Type: 0x%02x, Length: %d", subtype
, sublen
);
425 subtree
= proto_item_add_subtree(ti
, ett_isis_hello_clv_mt_port_cap_spb_digest
);
427 proto_tree_add_text( subtree
, tvb
, offset
, 1,
428 "V: %d, A: %d, D: %d",
435 proto_tree_add_text( subtree
, tvb
, offset
, DIGEST_LEN
, "Digest:");
436 for (i
= 0 ; i
< DIGEST_LEN
; i
+= 8, offset
+= 8) {
437 proto_tree_add_text( subtree
, tvb
, offset
, 8,
438 " %02x %02x %02x %02x %02x %02x %02x %02x",
439 digest
[i
+0], digest
[i
+1], digest
[i
+2], digest
[i
+3],
440 digest
[i
+4], digest
[i
+5], digest
[i
+6], digest
[i
+7]);
446 dissect_hello_mt_port_cap_spb_bvid_tuples_clv(tvbuff_t
*tvb
,
447 proto_tree
*tree
, int offset
, int subtype
, int sublen
)
449 proto_tree
*subtree
, *ti
;
452 ti
= proto_tree_add_text( tree
, tvb
, offset
-2, sublen
+2,
453 "SPB Base Vlan Identifiers: Type: 0x%02x, Length: %d", subtype
, sublen
);
454 subtree
= proto_item_add_subtree(ti
, ett_isis_hello_clv_mt_port_cap_spb_bvid_tuples
);
458 isis_dissect_unknown( tvb
, subtree
, offset
,
459 "Short SPB BVID header entry (%d vs %d)", sublen
, 6);
463 const guint8
*ect_tlv
= tvb_get_ptr(tvb
, subofs
, 6);
464 guint16 word
= (ect_tlv
[4] << 8) | ect_tlv
[5];
465 guint16 bvid
= (word
>> 4) & 0xfff;
466 int u_bit
= (ect_tlv
[5] & 8) ? 1 : 0;
467 int m_bit
= (ect_tlv
[5] & 4) ? 1 : 0;
468 proto_tree_add_text( subtree
, tvb
, subofs
, 6,
469 "ECT: %02x-%02x-%02x-%02x, BVID: 0x%03x (%d),%s U: %d, M: %d",
470 ect_tlv
[0], ect_tlv
[1], ect_tlv
[2], ect_tlv
[3],
485 dissect_hello_mt_port_cap_clv(tvbuff_t
*tvb
,
486 proto_tree
*tree
, int offset
, int id_length _U_
, int length
)
490 guint16 mtid
= tvb_get_ntohs(tvb
, offset
);
491 proto_tree_add_text( tree
, tvb
, offset
, 2,
496 while (length
>= 2) {
497 guint8 subtype
= tvb_get_guint8(tvb
, offset
);
498 guint8 subtlvlen
= tvb_get_guint8(tvb
, offset
+1);
501 if (subtlvlen
> length
) {
502 isis_dissect_unknown( tvb
, tree
, offset
,
503 "Short type 0x%02x TLV (%d vs %d)", subtype
, subtlvlen
, length
);
506 if (subtype
== 0x04) { /* SPB MCID */
507 dissect_hello_mt_port_cap_spb_mcid_clv(tvb
, tree
, offset
, subtype
, subtlvlen
);
509 else if (subtype
== 0x05) { /* SPB Digest */
510 dissect_hello_mt_port_cap_spb_digest_clv(tvb
, tree
, offset
, subtype
, subtlvlen
);
512 else if (subtype
== 0x06) { /* SPB BVID Tuples */
513 dissect_hello_mt_port_cap_spb_bvid_tuples_clv(tvb
, tree
, offset
, subtype
, subtlvlen
);
516 isis_dissect_unknown( tvb
, tree
, offset
,
517 "Unknown SubTlv: Type: 0x%02x, Length: %d", subtype
, subtlvlen
);
526 * The Restart CLV is documented in RFC 3847 (Restart Signaling for
527 * Intermediate System to Intermediate System). The CLV looks like this
530 * Length # of octets in the value field (1 to (3 + ID Length))
534 * +-----------------------+
536 * +-----------------------+
537 * | Remaining Time | 2
538 * +-----------------------+
539 * | Restarting Neighbor ID| ID Length
540 * +-----------------------+
545 * +--+--+--+--+--+--+--+--+
546 * | Reserved |SA|RA|RR|
547 * +--+--+--+--+--+--+--+--+
549 * RR - Restart Request
550 * RA - Restart Acknowledgement
551 * SA - Suppress adjacency advertisement
553 * The Remaining Time and Restarting Neighbor ID fields are only required when
554 * the RA flag is set. The Flags field is always required.
558 * Name: dissect_hello_restart_clv()
561 * Decode for a restart clv - only found in IIHs
562 * hence no call in the common clv dissector
567 dissect_hello_restart_clv(tvbuff_t
*tvb
,
568 proto_tree
*tree
, int offset
, int id_length
, int length
)
570 int restart_options
=0;
571 proto_tree
*flags_tree
;
572 proto_item
*restart_flags_item
;
573 proto_item
*hold_time_item
;
575 const guint8
*neighbor_id
;
578 restart_options
= tvb_get_guint8(tvb
, offset
);
579 restart_flags_item
= proto_tree_add_uint ( tree
, hf_isis_hello_clv_restart_flags
,
580 tvb
, offset
, 1, restart_options
);
581 flags_tree
= proto_item_add_subtree(restart_flags_item
, ett_isis_hello_clv_restart_flags
);
582 proto_tree_add_boolean (flags_tree
, hf_isis_hello_clv_restart_flags_sa
,
583 tvb
, offset
, 1, restart_options
);
584 proto_tree_add_boolean (flags_tree
, hf_isis_hello_clv_restart_flags_ra
,
585 tvb
, offset
, 1, restart_options
);
586 proto_tree_add_boolean (flags_tree
, hf_isis_hello_clv_restart_flags_rr
,
587 tvb
, offset
, 1, restart_options
);
589 /* Append an indication of which flags are set in the restart
593 APPEND_BOOLEAN_FLAG(ISIS_MASK_RESTART_SA(restart_options
), restart_flags_item
, "%sSA");
594 APPEND_BOOLEAN_FLAG(ISIS_MASK_RESTART_RA(restart_options
), restart_flags_item
, "%sRA");
595 APPEND_BOOLEAN_FLAG(ISIS_MASK_RESTART_RR(restart_options
), restart_flags_item
, "%sRR");
596 if (sep
!= initial_sep
)
598 proto_item_append_text (restart_flags_item
, ")");
603 /* The Remaining Time field should only be present if the RA flag is
606 if (length
>= 3 && ISIS_MASK_RESTART_RA(restart_options
)) {
607 hold_time_item
= proto_tree_add_uint ( tree
, hf_isis_hello_clv_restart_remain_time
,
608 tvb
, offset
+1, 2, tvb_get_ntohs(tvb
, offset
+1) );
609 proto_item_append_text( hold_time_item
, "s" );
612 /* The Restarting Neighbor ID should only be present if the RA flag is
615 if (length
>= 3 + id_length
&& ISIS_MASK_RESTART_RA(restart_options
)) {
616 neighbor_id
= tvb_get_ptr(tvb
, offset
+3, id_length
);
617 proto_tree_add_bytes_format_value( tree
,
618 hf_isis_hello_clv_restart_neighbor
, tvb
, offset
+3,
619 id_length
, neighbor_id
, "%s",
620 print_system_id( neighbor_id
, id_length
) );
625 * Name: dissect_hello_nlpid_clv()
628 * Decode for a hello packets NLPID clv. Calls into the
632 * tvbuff_t * : tvbuffer for packet data
633 * proto_tree * : proto tree to build on (may be null)
634 * int : current offset into packet data
635 * int : length of IDs in packet.
636 * int : length of this clv
639 * void, will modify proto_tree if not null.
642 dissect_hello_nlpid_clv(tvbuff_t
*tvb
,
643 proto_tree
*tree
, int offset
, int id_length _U_
, int length
)
645 isis_dissect_nlpid_clv(tvb
, tree
, offset
, length
);
649 * Name: dissect_hello_mt_clv()
652 * Decode for a hello packets Multi Topology clv. Calls into the
656 * tvbuff_t * : tvbuffer for packet data
657 * proto_tree * : proto tree to build on (may be null)
658 * int : current offset into packet data
659 * int : length of IDs in packet.
660 * int : length of this clv
663 * void, will modify proto_tree if not null.
667 dissect_hello_mt_clv(tvbuff_t
*tvb
,
668 proto_tree
*tree
, int offset
, int id_length _U_
, int length
)
670 isis_dissect_mt_clv(tvb
, tree
, offset
, length
,
671 hf_isis_hello_clv_mt
);
675 * Name: dissect_hello_ip_int_addr_clv()
678 * Decode for a hello packets ip interface addr clv. Calls into the
682 * tvbuff_t * : tvbuffer for packet data
683 * proto_tree * : proto tree to build on (may be null)
684 * int : current offset into packet data
685 * int : length of IDs in packet.
686 * int : length of this clv
689 * void, will modify proto_tree if not null.
692 dissect_hello_ip_int_addr_clv(tvbuff_t
*tvb
,
693 proto_tree
*tree
, int offset
, int id_length _U_
, int length
)
695 isis_dissect_ip_int_clv(tvb
, tree
, offset
, length
,
696 hf_isis_hello_clv_ipv4_int_addr
);
700 * Name: dissect_hello_ipv6_int_addr_clv()
703 * Decode for a hello packets ipv6 interface addr clv. Calls into the
707 * tvbuff_t * : tvbuffer for packet data
708 * proto_tree * : proto tree to build on (may be null)
709 * int : current offset into packet data
710 * int : length of IDs in packet.
711 * int : length of this clv
714 * void, will modify proto_tree if not null.
717 dissect_hello_ipv6_int_addr_clv(tvbuff_t
*tvb
,
718 proto_tree
*tree
, int offset
, int id_length _U_
, int length
)
720 isis_dissect_ipv6_int_clv(tvb
, tree
, offset
, length
,
721 hf_isis_hello_clv_ipv6_int_addr
);
725 * Name: dissect_hello_authentication_clv()
728 * Decode for a hello packets authenticaion clv.
729 * Calls into the CLV common one.
732 * tvbuff_t * : tvbuffer for packet data
733 * proto_tree * : proto tree to build on (may be null)
734 * int : current offset into packet data
735 * int : length of IDs in packet.
736 * int : length of this clv
739 * void, will modify proto_tree if not null.
742 dissect_hello_authentication_clv(tvbuff_t
*tvb
,
743 proto_tree
*tree
, int offset
, int id_length _U_
, int length
)
745 isis_dissect_authentication_clv(tvb
, tree
, offset
, length
);
749 * Name: dissect_hello_ip_authentication_clv()
752 * Decode for a hello packets IP authenticaion clv.
753 * Calls into the CLV common one.
756 * tvbuff_t * : tvbuffer for packet data
757 * proto_tree * : proto tree to build on (may be null)
758 * int : current offset into packet data
759 * int : length of IDs in packet.
760 * int : length of this clv
763 * void, will modify proto_tree if not null.
766 dissect_hello_ip_authentication_clv(tvbuff_t
*tvb
,
767 proto_tree
*tree
, int offset
, int id_length _U_
, int length
)
769 isis_dissect_ip_authentication_clv(tvb
, tree
, offset
, length
);
773 * Name: dissect_hello_checksum_clv()
776 * dump and verify the optional checksum in TLV 12
779 * tvbuff_t * : tvbuffer for packet data
780 * proto_tree * : protocol display tree to fill out. May be NULL
781 * int : offset into packet data where we are.
782 * int : length of clv we are decoding
785 * void, but we will add to proto tree if !NULL.
789 dissect_hello_checksum_clv(tvbuff_t
*tvb
,
790 proto_tree
*tree
, int offset
, int id_length _U_
, int length
) {
792 guint16 pdu_length
,checksum
, cacl_checksum
=0;
796 proto_tree_add_text ( tree
, tvb
, offset
, length
,
797 "incorrect checksum length (%u), should be (2)", length
);
801 checksum
= tvb_get_ntohs(tvb
, offset
);
803 /* the check_and_get_checksum() function needs to know how big
804 * the packet is. we can either pass through the pdu-len through several layers
805 * of dissectors and wrappers or extract the PDU length field from the PDU specific header
806 * which is offseted 17 bytes in IIHs (relative to the beginning of the IS-IS packet) */
808 pdu_length
= tvb_get_ntohs(tvb
, 17);
810 /* unlike the LSP checksum verification which starts at an offset of 12 we start at offset 0*/
811 switch (check_and_get_checksum(tvb
, 0, pdu_length
, checksum
, offset
, &cacl_checksum
))
815 proto_tree_add_text ( tree
, tvb
, offset
, length
,
816 "Checksum: 0x%04x [unused]", checksum
);
819 isis_dissect_unknown(tvb
, tree
, offset
,
820 "[packet length %d went beyond packet]",
824 proto_tree_add_text ( tree
, tvb
, offset
, length
,
825 "Checksum: 0x%04x [incorrect, should be 0x%04x]",
830 proto_tree_add_text ( tree
, tvb
, offset
, length
,
831 "Checksum: 0x%04x [correct]", checksum
);
834 g_message("'check_and_get_checksum' returned an invalid value");
842 * Name: dissect_hello_area_address_clv()
845 * Decode for a hello packets area address clv.
846 * Calls into the CLV common one.
849 * tvbuff_t * : tvbuffer for packet data
850 * proto_tree * : proto tree to build on (may be null)
851 * int : current offset into packet data
852 * int : length of IDs in packet.
853 * int : length of this clv
856 * void, will modify proto_tree if not null.
859 dissect_hello_area_address_clv(tvbuff_t
*tvb
,
860 proto_tree
*tree
, int offset
, int id_length _U_
, int length
)
862 isis_dissect_area_address_clv(tvb
, tree
, offset
, length
);
868 dissect_hello_ptp_adj_clv(tvbuff_t
*tvb
,
869 proto_tree
*tree
, int offset
, int id_length
, int length
)
871 static const value_string adj_state_vals
[] = {
873 { 1, "Initializing" },
878 const char *adj_state_str
;
880 adj_state
= tvb_get_guint8(tvb
, offset
);
881 adj_state_str
= val_to_str(adj_state
, adj_state_vals
, "Unknown (%u)");
884 proto_tree_add_text ( tree
, tvb
, offset
, 1,
885 "Adjacency State: %s", adj_state_str
);
888 proto_tree_add_text ( tree
, tvb
, offset
, 1,
889 "Adjacency State: %s", adj_state_str
);
890 proto_tree_add_text ( tree
, tvb
, offset
+1, 4,
891 "Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb
, offset
+1) );
894 proto_tree_add_text ( tree
, tvb
, offset
, 1,
895 "Adjacency State: %s", adj_state_str
);
896 proto_tree_add_text ( tree
, tvb
, offset
+1, 4,
897 "Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb
, offset
+1) );
898 proto_tree_add_text ( tree
, tvb
, offset
+5, id_length
,
899 "Neighbor SystemID: %s",
900 print_system_id( tvb_get_ptr(tvb
, offset
+5, id_length
), id_length
) );
903 proto_tree_add_text ( tree
, tvb
, offset
, 1,
904 "Adjacency State: %s", adj_state_str
);
905 proto_tree_add_text ( tree
, tvb
, offset
+1, 4,
906 "Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb
, offset
+1) );
907 proto_tree_add_text ( tree
, tvb
, offset
+5, id_length
,
908 "Neighbor SystemID: %s",
909 print_system_id( tvb_get_ptr(tvb
, offset
+5, id_length
), id_length
) );
910 proto_tree_add_text ( tree
, tvb
, offset
+5+id_length
, 4,
911 "Neighbor Extended Local circuit ID: 0x%08x",
912 tvb_get_ntohl(tvb
, offset
+5+id_length
) );
915 isis_dissect_unknown(tvb
, tree
, offset
,
916 "malformed TLV (%d vs 1,5,11,15)", length
);
922 * Name: isis_dissect_is_neighbors_clv()
925 * Take apart a IS neighbor packet. A neighbor is n 6 byte packets.
926 * (they tend to be an 802.3 MAC address, but it's not required).
929 * tvbuff_t * : tvbuffer for packet data
930 * proto_tree * : protocol display tree to fill out. May be NULL
931 * int : offset into packet data where we are.
932 * int : length of IDs in packet.
933 * int : length of clv we are decoding
936 * void, but we will add to proto tree if !NULL.
939 dissect_hello_is_neighbors_clv(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
,
940 int id_length _U_
, int length
)
942 while ( length
> 0 ) {
944 isis_dissect_unknown(tvb
, tree
, offset
,
945 "short is neighbor (%d vs 6)", length
);
949 * Lets turn the area address into "standard" 0000.0000.etc
953 proto_tree_add_text ( tree
, tvb
, offset
, 6,
954 "IS Neighbor: %s", get_ether_name( tvb_get_ptr(tvb
, offset
, 6)) );
962 * Name: dissect_hello_padding_clv()
965 * Decode for a hello packet's padding clv. Padding does nothing,
969 * tvbuff_t * : tvbuffer for packet data
970 * proto_tree * : proto tree to build on (may be null)
971 * int : current offset into packet data
972 * int : length of IDs in packet.
973 * int : length of this clv
979 dissect_hello_padding_clv(tvbuff_t
*tvb _U_
, proto_tree
*tree _U_
, int offset _U_
,
980 int id_length _U_
, int length _U_
)
982 /* nothing to do here! */
987 * Name: isis_dissect_isis_hello()
990 * This procedure rips apart the various types of ISIS hellos. L1H and
991 * L2H's are identical for the most part, while the PTP hello has
995 * tvbuff_t * : tvbuffer for packet data
996 * proto_tree * : protocol display tree to add to. May be NULL.
997 * int offset : our offset into packet data.
998 * int : hello type, a la packet-isis.h ISIS_TYPE_* values
999 * int : header length of packet.
1000 * int : length of IDs in packet.
1003 * void, will modify proto_tree if not NULL.
1006 isis_dissect_isis_hello(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
,
1007 int hello_type
, int header_length
, int id_length
)
1010 proto_tree
*hello_tree
= NULL
;
1013 const guint8
*source_id
;
1015 const guint8
*lan_id
;
1018 ti
= proto_tree_add_text(tree
, tvb
, offset
, -1, "ISIS HELLO");
1019 hello_tree
= proto_item_add_subtree(ti
, ett_isis_hello
);
1020 octet
= tvb_get_guint8(tvb
, offset
);
1021 proto_tree_add_uint_format(hello_tree
,
1022 hf_isis_hello_circuit_reserved
,
1023 tvb
, offset
, 1, octet
,
1024 "Circuit type : %s, reserved(0x%02x == 0)",
1025 val_to_str(octet
&ISIS_HELLO_CTYPE_MASK
,
1026 isis_hello_circuit_type_vals
,
1028 octet
&ISIS_HELLO_CT_RESERVED_MASK
1034 source_id
= tvb_get_ptr(tvb
, offset
, id_length
);
1035 proto_tree_add_bytes_format_value(hello_tree
, hf_isis_hello_source_id
, tvb
,
1036 offset
, id_length
, source_id
,
1037 "%s", print_system_id( source_id
, id_length
) );
1039 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", System-ID: %s",
1040 print_system_id( tvb_get_ptr(tvb
, offset
, id_length
), id_length
) );
1042 offset
+= id_length
;
1045 proto_tree_add_item(hello_tree
, hf_isis_hello_holding_timer
, tvb
,
1046 offset
, 2, ENC_BIG_ENDIAN
);
1050 pdu_length
= tvb_get_ntohs(tvb
, offset
);
1052 proto_tree_add_uint(hello_tree
, hf_isis_hello_pdu_length
, tvb
,
1053 offset
, 2, pdu_length
);
1057 if (hello_type
== ISIS_TYPE_PTP_HELLO
) {
1059 proto_tree_add_item(hello_tree
, hf_isis_hello_local_circuit_id
, tvb
,
1060 offset
, 1, ENC_BIG_ENDIAN
);
1065 octet
= tvb_get_guint8(tvb
, offset
);
1066 proto_tree_add_uint_format(hello_tree
, hf_isis_hello_priority_reserved
, tvb
,
1068 "Priority : %d, reserved(0x%02x == 0)",
1069 octet
&ISIS_HELLO_PRIORITY_MASK
,
1070 octet
&ISIS_HELLO_P_RESERVED_MASK
);
1075 lan_id
= tvb_get_ptr(tvb
, offset
, id_length
+1);
1076 proto_tree_add_bytes_format_value(hello_tree
, hf_isis_hello_lan_id
, tvb
,
1077 offset
, id_length
+ 1, lan_id
,
1078 "%s", print_system_id( lan_id
, id_length
+ 1 ) );
1080 offset
+= id_length
+ 1;
1084 len
-= header_length
;
1086 isis_dissect_unknown(tvb
, tree
, offset
,
1087 "Packet header length %d went beyond packet",
1092 * Now, we need to decode our CLVs. We need to pass in
1093 * our list of valid ones!
1095 if (hello_type
== ISIS_TYPE_L1_HELLO
){
1096 isis_dissect_clvs(tvb
, hello_tree
, offset
,
1097 clv_l1_hello_opts
, len
, id_length
,
1098 ett_isis_hello_clv_unknown
);
1099 } else if (hello_type
== ISIS_TYPE_L2_HELLO
) {
1100 isis_dissect_clvs(tvb
, hello_tree
, offset
,
1101 clv_l2_hello_opts
, len
, id_length
,
1102 ett_isis_hello_clv_unknown
);
1104 isis_dissect_clvs(tvb
, hello_tree
, offset
,
1105 clv_ptp_hello_opts
, len
, id_length
,
1106 ett_isis_hello_clv_unknown
);
1111 * Name: isis_register_hello()
1114 * Register our protocol sub-sets with protocol manager.
1117 * int : protocol index for the ISIS protocol
1123 isis_register_hello(int proto_isis
) {
1124 static hf_register_info hf
[] = {
1125 { &hf_isis_hello_circuit_reserved
,
1126 { "Circuit type", "isis.hello.circuit_type",
1127 FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
1129 { &hf_isis_hello_source_id
,
1130 { "SystemID {Sender of PDU}", "isis.hello.source_id",
1131 FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
1133 { &hf_isis_hello_holding_timer
,
1134 { "Holding timer", "isis.hello.holding_timer",
1135 FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1137 { &hf_isis_hello_pdu_length
,
1138 { "PDU length", "isis.hello.pdu_length",
1139 FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1141 { &hf_isis_hello_priority_reserved
,
1142 { "Priority", "isis.hello.priority",
1143 FT_UINT8
, BASE_DEC
, NULL
, ISIS_HELLO_P_RESERVED_MASK
, NULL
, HFILL
}},
1145 { &hf_isis_hello_lan_id
,
1146 { "SystemID {Designated IS}", "isis.hello.lan_id",
1147 FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
1149 { &hf_isis_hello_local_circuit_id
,
1150 { "Local circuit ID", "isis.hello.local_circuit_id",
1151 FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1153 { &hf_isis_hello_clv_ipv4_int_addr
,
1154 { "IPv4 interface address", "isis.hello.clv_ipv4_int_addr",
1155 FT_IPv4
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
1157 { &hf_isis_hello_clv_ipv6_int_addr
,
1158 { "IPv6 interface address", "isis.hello.clv_ipv6_int_addr",
1159 FT_IPv6
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
1162 { &hf_isis_hello_clv_ptp_adj
,
1163 { "Point-to-point Adjacency", "isis.hello.clv_ptp_adj",
1164 FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1167 { &hf_isis_hello_clv_mt
,
1168 { "MT-ID", "isis.hello.clv_mt",
1169 FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
1171 { &hf_isis_hello_clv_restart_flags
,
1172 { "Restart Signaling Flags", "isis.hello.clv_restart_flags",
1173 FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
1175 { &hf_isis_hello_clv_restart_flags_rr
,
1176 { "Restart Request", "isis.hello.clv_restart_flags.rr",
1177 FT_BOOLEAN
, 8, TFS(&tfs_true_false
), ISIS_RESTART_RR
,
1178 "When set, the router is beginning a graceful restart", HFILL
}},
1180 { &hf_isis_hello_clv_restart_flags_ra
,
1181 { "Restart Acknowledgment", "isis.hello.clv_restart_flags.ra",
1182 FT_BOOLEAN
, 8, TFS(&tfs_true_false
), ISIS_RESTART_RA
,
1183 "When set, the router is willing to enter helper mode", HFILL
}},
1185 { &hf_isis_hello_clv_restart_flags_sa
,
1186 { "Suppress Adjacency", "isis.hello.clv_restart_flags.sa",
1187 FT_BOOLEAN
, 8, TFS(&tfs_true_false
), ISIS_RESTART_SA
,
1188 "When set, the router is starting as opposed to restarting", HFILL
}},
1190 { &hf_isis_hello_clv_restart_remain_time
,
1191 { "Remaining holding time", "isis.hello.clv_restart.remain_time",
1192 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1193 "How long the helper router will maintain the existing adjacency", HFILL
}},
1195 { &hf_isis_hello_clv_restart_neighbor
,
1196 { "Restarting Neighbor ID", "isis.hello.clv_restart.neighbor",
1197 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1198 "The System ID of the restarting neighbor", HFILL
}}
1200 static gint
*ett
[] = {
1202 &ett_isis_hello_clv_area_addr
,
1203 &ett_isis_hello_clv_is_neighbors
,
1204 &ett_isis_hello_clv_padding
,
1205 &ett_isis_hello_clv_unknown
,
1206 &ett_isis_hello_clv_nlpid
,
1207 &ett_isis_hello_clv_authentication
,
1208 &ett_isis_hello_clv_ip_authentication
,
1209 &ett_isis_hello_clv_ipv4_int_addr
,
1210 &ett_isis_hello_clv_ipv6_int_addr
,
1211 &ett_isis_hello_clv_ptp_adj
,
1212 &ett_isis_hello_clv_mt
,
1213 &ett_isis_hello_clv_restart
,
1214 &ett_isis_hello_clv_restart_flags
,
1215 &ett_isis_hello_clv_mt_port_cap
,
1216 &ett_isis_hello_clv_mt_port_cap_spb_mcid
,
1217 &ett_isis_hello_clv_mt_port_cap_spb_aux_mcid
,
1218 &ett_isis_hello_clv_mt_port_cap_spb_digest
,
1219 &ett_isis_hello_clv_mt_port_cap_spb_bvid_tuples
,
1220 &ett_isis_hello_clv_checksum
1223 proto_register_field_array(proto_isis
, hf
, array_length(hf
));
1224 proto_register_subtree_array(ett
, array_length(ett
));