2 * Routines for decoding isis hello packets and their CLVs
4 * $Id: packet-isis-hello.c,v 1.23 2001/12/20 07:33:21 guy Exp $
5 * Stuart Stanley <stuarts@mxmail.net>
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 #ifdef HAVE_SYS_TYPES_H
31 # include <sys/types.h>
38 #include "packet-osi.h"
39 #include "packet-isis.h"
40 #include "packet-isis-clv.h"
41 #include "packet-isis-hello.h"
44 static int hf_isis_hello_circuit_reserved = -1;
45 static int hf_isis_hello_source_id = -1;
46 static int hf_isis_hello_holding_timer = -1;
47 static int hf_isis_hello_pdu_length = -1;
48 static int hf_isis_hello_priority_reserved = -1;
49 static int hf_isis_hello_lan_id = -1;
50 static int hf_isis_hello_local_circuit_id = -1;
51 static int hf_isis_hello_clv_ipv4_int_addr = -1;
52 static int hf_isis_hello_clv_ipv6_int_addr = -1;
53 static int hf_isis_hello_clv_ptp_adj = -1;
54 static int hf_isis_hello_clv_mt = -1;
56 static gint ett_isis_hello = -1;
57 static gint ett_isis_hello_clv_area_addr = -1;
58 static gint ett_isis_hello_clv_is_neighbors = -1;
59 static gint ett_isis_hello_clv_padding = -1;
60 static gint ett_isis_hello_clv_unknown = -1;
61 static gint ett_isis_hello_clv_nlpid = -1;
62 static gint ett_isis_hello_clv_auth = -1;
63 static gint ett_isis_hello_clv_ipv4_int_addr = -1;
64 static gint ett_isis_hello_clv_ipv6_int_addr = -1;
65 static gint ett_isis_hello_clv_ptp_adj = -1;
66 static gint ett_isis_hello_clv_mt = -1;
68 static const value_string isis_hello_circuit_type_vals[] = {
69 { ISIS_HELLO_TYPE_RESERVED, "Reserved 0 (discard PDU)"},
70 { ISIS_HELLO_TYPE_LEVEL_1, "Level 1 only"},
71 { ISIS_HELLO_TYPE_LEVEL_2, "Level 2 only"},
72 { ISIS_HELLO_TYPE_LEVEL_12, "Level 1 and 2"},
76 * Predclare dissectors for use in clv dissection.
78 static void dissect_hello_padding_clv(tvbuff_t *tvb,
79 packet_info *pinfo, proto_tree *tree, int offset,
80 int id_length, int length);
81 static void dissect_hello_is_neighbors_clv(tvbuff_t *tvb,
82 packet_info *pinfo, proto_tree *tree, int offset,
83 int id_length, int length);
84 static void dissect_hello_ptp_adj_clv(tvbuff_t *tvb,
85 packet_info *pinfo, proto_tree *tree, int offset,
86 int id_length, int length);
87 static void dissect_hello_area_address_clv(tvbuff_t *tvb,
88 packet_info *pinfo, proto_tree *tree, int offset,
89 int id_length, int length);
90 static void dissect_hello_auth_clv(tvbuff_t *tvb,
91 packet_info *pinfo, proto_tree *tree, int offset,
92 int id_length, int length);
93 static void dissect_hello_ipv6_int_addr_clv(tvbuff_t *tvb,
94 packet_info *pinfo, proto_tree *tree, int offset,
95 int id_length, int length);
96 static void dissect_hello_ip_int_addr_clv(tvbuff_t *tvb,
97 packet_info *pinfo, proto_tree *tree, int offset,
98 int id_length, int length);
99 static void dissect_hello_mt_clv(tvbuff_t *tvb,
100 packet_info *pinfo, proto_tree *tree, int offset,
101 int id_length, int length);
102 static void dissect_hello_nlpid_clv(tvbuff_t *tvb,
103 packet_info *pinfo, proto_tree *tree, int offset,
104 int id_length, int length);
107 static const isis_clv_handle_t clv_l1_hello_opts[] = {
109 ISIS_CLV_L1H_AREA_ADDRESS,
111 &ett_isis_hello_clv_area_addr,
112 dissect_hello_area_address_clv
115 ISIS_CLV_L1H_IS_NEIGHBORS,
117 &ett_isis_hello_clv_is_neighbors,
118 dissect_hello_is_neighbors_clv
121 ISIS_CLV_L1H_PADDING,
123 &ett_isis_hello_clv_padding,
124 dissect_hello_padding_clv
128 "Protocols Supported",
129 &ett_isis_hello_clv_nlpid,
130 dissect_hello_nlpid_clv
133 ISIS_CLV_L1H_IP_INTERFACE_ADDR,
134 "IP Interface address(es)",
135 &ett_isis_hello_clv_ipv4_int_addr,
136 dissect_hello_ip_int_addr_clv
139 ISIS_CLV_L1H_IPv6_INTERFACE_ADDR,
140 "IPv6 Interface address(es)",
141 &ett_isis_hello_clv_ipv6_int_addr,
142 dissect_hello_ipv6_int_addr_clv
145 ISIS_CLV_L1H_AUTHENTICATION_NS,
146 "Authentication(non spec)",
147 &ett_isis_hello_clv_auth,
148 dissect_hello_auth_clv
151 ISIS_CLV_L1H_AUTHENTICATION,
153 &ett_isis_hello_clv_auth,
154 dissect_hello_auth_clv
159 &ett_isis_hello_clv_mt,
170 static const isis_clv_handle_t clv_l2_hello_opts[] = {
172 ISIS_CLV_L2H_AREA_ADDRESS,
174 &ett_isis_hello_clv_area_addr,
175 dissect_hello_area_address_clv
178 ISIS_CLV_L2H_IS_NEIGHBORS,
180 &ett_isis_hello_clv_is_neighbors,
181 dissect_hello_is_neighbors_clv
184 ISIS_CLV_L2H_PADDING,
186 &ett_isis_hello_clv_padding,
187 dissect_hello_padding_clv
191 "Protocols Supported",
192 &ett_isis_hello_clv_nlpid,
193 dissect_hello_nlpid_clv
196 ISIS_CLV_L2H_IP_INTERFACE_ADDR,
197 "IP Interface address(es)",
198 &ett_isis_hello_clv_ipv4_int_addr,
199 dissect_hello_ip_int_addr_clv
202 ISIS_CLV_L2H_IPv6_INTERFACE_ADDR,
203 "IPv6 Interface address(es)",
204 &ett_isis_hello_clv_ipv6_int_addr,
205 dissect_hello_ipv6_int_addr_clv
208 ISIS_CLV_L2H_AUTHENTICATION_NS,
209 "Authentication(non spec)",
210 &ett_isis_hello_clv_auth,
211 dissect_hello_auth_clv
214 ISIS_CLV_L2H_AUTHENTICATION,
216 &ett_isis_hello_clv_auth,
217 dissect_hello_auth_clv
222 &ett_isis_hello_clv_mt,
233 static const isis_clv_handle_t clv_ptp_hello_opts[] = {
235 ISIS_CLV_PTP_AREA_ADDRESS,
237 &ett_isis_hello_clv_area_addr,
238 dissect_hello_area_address_clv
241 ISIS_CLV_PTP_PADDING,
243 &ett_isis_hello_clv_padding,
244 dissect_hello_padding_clv
248 "Protocols Supported",
249 &ett_isis_hello_clv_nlpid,
250 dissect_hello_nlpid_clv
253 ISIS_CLV_PTP_IP_INTERFACE_ADDR,
254 "IP Interface address(es)",
255 &ett_isis_hello_clv_ipv4_int_addr,
256 dissect_hello_ip_int_addr_clv
259 ISIS_CLV_PTP_IPv6_INTERFACE_ADDR,
260 "IPv6 Interface address(es)",
261 &ett_isis_hello_clv_ipv6_int_addr,
262 dissect_hello_ipv6_int_addr_clv
265 ISIS_CLV_PTP_AUTHENTICATION_NS,
266 "Authentication(non spec)",
267 &ett_isis_hello_clv_auth,
268 dissect_hello_auth_clv
271 ISIS_CLV_PTP_AUTHENTICATION,
273 &ett_isis_hello_clv_auth,
274 dissect_hello_auth_clv
278 "Point-to-point Adjacency State",
279 &ett_isis_hello_clv_ptp_adj,
280 dissect_hello_ptp_adj_clv
285 &ett_isis_hello_clv_mt,
297 * Name: dissect_hello_nlpid_clv()
300 * Decode for a hello packets NLPID clv. Calls into the
304 * tvbuff_t * : tvbuffer for packet data
305 * packet_info * : info for current packet
306 * proto_tree * : proto tree to build on (may be null)
307 * int : current offset into packet data
308 * int : length of IDs in packet.
309 * int : length of this clv
312 * void, will modify proto_tree if not null.
315 dissect_hello_nlpid_clv(tvbuff_t *tvb,
316 packet_info *pinfo, proto_tree *tree, int offset,
317 int id_length, int length)
319 isis_dissect_nlpid_clv(tvb, pinfo, tree, offset, length);
323 * Name: dissect_hello_mt_clv()
326 * Decode for a hello packets Multi Topology clv. Calls into the
330 * tvbuff_t * : tvbuffer for packet data
331 * packet_info * : info for current packet
332 * proto_tree * : proto tree to build on (may be null)
333 * int : current offset into packet data
334 * int : length of IDs in packet.
335 * int : length of this clv
338 * void, will modify proto_tree if not null.
342 dissect_hello_mt_clv(tvbuff_t *tvb,
343 packet_info *pinfo, proto_tree *tree, int offset,
344 int id_length, int length)
346 isis_dissect_mt_clv(tvb, pinfo, tree, offset, length,
347 hf_isis_hello_clv_mt );
351 * Name: dissect_hello_ip_int_addr_clv()
354 * Decode for a hello packets ip interface addr clv. Calls into the
358 * tvbuff_t * : tvbuffer for packet data
359 * packet_info * : info for current packet
360 * proto_tree * : proto tree to build on (may be null)
361 * int : current offset into packet data
362 * int : length of IDs in packet.
363 * int : length of this clv
366 * void, will modify proto_tree if not null.
369 dissect_hello_ip_int_addr_clv(tvbuff_t *tvb,
370 packet_info *pinfo, proto_tree *tree, int offset,
371 int id_length, int length)
373 isis_dissect_ip_int_clv(tvb, pinfo, tree, offset, length,
374 hf_isis_hello_clv_ipv4_int_addr );
378 * Name: dissect_hello_ipv6_int_addr_clv()
381 * Decode for a hello packets ipv6 interface addr clv. Calls into the
385 * tvbuff_t * : tvbuffer for packet data
386 * packet_info * : info for current packet
387 * proto_tree * : proto tree to build on (may be null)
388 * int : current offset into packet data
389 * int : length of IDs in packet.
390 * int : length of this clv
393 * void, will modify proto_tree if not null.
396 dissect_hello_ipv6_int_addr_clv(tvbuff_t *tvb,
397 packet_info *pinfo, proto_tree *tree, int offset,
398 int id_length, int length)
400 isis_dissect_ipv6_int_clv(tvb, pinfo, tree, offset, length,
401 hf_isis_hello_clv_ipv6_int_addr );
405 * Name: dissect_hello_auth_clv()
408 * Decode for a hello packets authenticaion clv. Calls into the
409 * clv common one. An auth inside a hello packet is a perlink
413 * tvbuff_t * : tvbuffer for packet data
414 * packet_info * : info for current packet
415 * proto_tree * : proto tree to build on (may be null)
416 * int : current offset into packet data
417 * int : length of IDs in packet.
418 * int : length of this clv
421 * void, will modify proto_tree if not null.
424 dissect_hello_auth_clv(tvbuff_t *tvb,
425 packet_info *pinfo, proto_tree *tree, int offset,
426 int id_length, int length)
428 isis_dissect_authentication_clv(tvb, pinfo, tree, offset,
429 length, "authentication" );
433 * Name: dissect_hello_area_address_clv()
436 * Decode for a hello packets area address clv. Calls into the
440 * tvbuff_t * : tvbuffer for packet data
441 * packet_info * : info for current packet
442 * proto_tree * : proto tree to build on (may be null)
443 * int : current offset into packet data
444 * int : length of IDs in packet.
445 * int : length of this clv
448 * void, will modify proto_tree if not null.
451 dissect_hello_area_address_clv(tvbuff_t *tvb,
452 packet_info *pinfo, proto_tree *tree, int offset,
453 int id_length, int length)
455 isis_dissect_area_address_clv(tvb, pinfo, tree, offset, length);
461 dissect_hello_ptp_adj_clv(tvbuff_t *tvb,
462 packet_info *pinfo, proto_tree *tree, int offset,
463 int id_length, int length)
467 switch(tvb_get_guint8(tvb, offset)) {
469 strcpy(adj_state,"Up");
472 strcpy(adj_state,"Initializing");
475 strcpy(adj_state,"Down");
478 strcpy(adj_state,"<illegal value !!!>");
483 proto_tree_add_text ( tree, tvb, offset, 1,
484 "Adjacency State: %s", adj_state );
487 proto_tree_add_text ( tree, tvb, offset, 1,
488 "Adjacency State: %s", adj_state );
489 proto_tree_add_text ( tree, tvb, offset+1, 4,
490 "Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+1) );
493 proto_tree_add_text ( tree, tvb, offset, 1,
494 "Adjacency State: %s", adj_state );
495 proto_tree_add_text ( tree, tvb, offset+1, 4,
496 "Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+1) );
497 proto_tree_add_text ( tree, tvb, offset+5, 6,
498 "Neighbor SystemID: %s", print_system_id( tvb_get_ptr(tvb, offset+5, 6), 6 ) );
501 proto_tree_add_text ( tree, tvb, offset, 1,
502 "Adjacency State: %s", adj_state );
503 proto_tree_add_text ( tree, tvb, offset+1, 4,
504 "Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+1) );
505 proto_tree_add_text ( tree, tvb, offset+5, 6,
506 "Neighbor SystemID: %s", print_system_id( tvb_get_ptr(tvb, offset+5, 6), 6 ) );
507 proto_tree_add_text ( tree, tvb, offset+11, 4,
508 "Neighbor Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+11) );
511 isis_dissect_unknown(tvb, pinfo, tree, offset,
512 "malformed TLV (%d vs 1,5,11,15)", length );
518 * Name: isis_dissect_is_neighbors_clv()
521 * Take apart a IS neighbor packet. A neighbor is n 6 byte packets.
522 * (they tend to be an 802.3 MAC address, but its not required).
525 * tvbuff_t * : tvbuffer for packet data
526 * packet_info * : info for current packet
527 * proto_tree * : protocol display tree to fill out. May be NULL
528 * int : offset into packet data where we are.
529 * int : length of IDs in packet.
530 * int : length of clv we are decoding
533 * void, but we will add to proto tree if !NULL.
536 dissect_hello_is_neighbors_clv(tvbuff_t *tvb, packet_info *pinfo,
537 proto_tree *tree, int offset, int id_length, int length)
539 while ( length > 0 ) {
541 isis_dissect_unknown(tvb, pinfo, tree, offset,
542 "short is neighbor (%d vs 6)", length );
546 * Lets turn the area address into "standard" 0000.0000.etc
550 proto_tree_add_text ( tree, tvb, offset, 6,
551 "IS Neighbor: %s", print_system_id( tvb_get_ptr(tvb, offset, 6), 6 ) );
559 * Name: dissect_hello_padding_clv()
562 * Decode for a hello packet's padding clv. Padding does nothing,
566 * tvbuff_t * : tvbuffer for packet data
567 * packet_info * : info for current packet
568 * proto_tree * : proto tree to build on (may be null)
569 * int : current offset into packet data
570 * int : length of IDs in packet.
571 * int : length of this clv
577 dissect_hello_padding_clv(tvbuff_t *tvb, packet_info *pinfo,
578 proto_tree *tree, int offset, int id_length, int length)
580 /* nothing to do here! */
585 * Name: isis_dissect_isis_hello()
588 * This procedure rips apart the various types of ISIS hellos. L1H and
589 * L2H's are identical for the most part, while the PTP hello has
593 * tvbuff_t * : tvbuffer for packet data
594 * packet_info * : info for current packet
595 * proto_tree * : protocol display tree to add to. May be NULL.
596 * int offset : our offset into packet data.
597 * int : hello type, a la packet-isis.h ISIS_TYPE_* values
598 * int : header length of packet.
599 * int : length of IDs in packet.
602 * void, will modify proto_tree if not NULL.
605 isis_dissect_isis_hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
606 int offset, int hello_type, int header_length, int id_length)
609 proto_tree *hello_tree = NULL;
612 const guint8 *source_id;
614 const guint8 *lan_id;
617 ti = proto_tree_add_text(tree, tvb, offset,
618 tvb_length_remaining(tvb, offset), "ISIS HELLO");
619 hello_tree = proto_item_add_subtree(ti, ett_isis_hello);
620 octet = tvb_get_guint8(tvb, offset);
621 proto_tree_add_uint_format(hello_tree,
622 hf_isis_hello_circuit_reserved,
623 tvb, offset, 1, octet,
624 "Circuit type : %s, reserved(0x%02x == 0)",
625 val_to_str(octet&ISIS_HELLO_CTYPE_MASK,
626 isis_hello_circuit_type_vals,
628 octet&ISIS_HELLO_CT_RESERVED_MASK
634 source_id = tvb_get_ptr(tvb, offset, id_length);
635 proto_tree_add_bytes_format(hello_tree, hf_isis_hello_source_id, tvb,
636 offset, id_length, source_id,
637 "SystemID{ Sender of PDU } : %s",
638 print_system_id( source_id, id_length ) );
643 proto_tree_add_item(hello_tree, hf_isis_hello_holding_timer, tvb,
648 pdu_length = tvb_get_ntohs(tvb, offset);
650 proto_tree_add_uint(hello_tree, hf_isis_hello_pdu_length, tvb,
651 offset, 2, pdu_length);
655 if (hello_type == ISIS_TYPE_PTP_HELLO) {
657 proto_tree_add_item(hello_tree, hf_isis_hello_local_circuit_id, tvb,
664 octet = tvb_get_guint8(tvb, offset);
665 proto_tree_add_uint_format(hello_tree, hf_isis_hello_priority_reserved, tvb,
667 "Priority : %d, reserved(0x%02x == 0)",
668 octet&ISIS_HELLO_PRIORITY_MASK,
669 octet&ISIS_HELLO_P_RESERVED_MASK );
674 lan_id = tvb_get_ptr(tvb, offset, id_length+1);
675 proto_tree_add_bytes_format(hello_tree, hf_isis_hello_lan_id, tvb,
676 offset, id_length + 1, lan_id,
677 "SystemID{ Designated IS } : %s",
678 print_system_id( lan_id, id_length + 1 ) );
680 offset += id_length + 1;
684 len -= header_length;
686 isis_dissect_unknown(tvb, pinfo, tree, offset,
687 "Packet header length %d went beyond packet",
692 * Now, we need to decode our CLVs. We need to pass in
693 * our list of valid ones!
695 if (hello_type == ISIS_TYPE_L1_HELLO){
696 isis_dissect_clvs(tvb, pinfo, hello_tree, offset,
697 clv_l1_hello_opts, len, id_length,
698 ett_isis_hello_clv_unknown);
699 } else if (hello_type == ISIS_TYPE_L2_HELLO) {
700 isis_dissect_clvs(tvb, pinfo, hello_tree, offset,
701 clv_l2_hello_opts, len, id_length,
702 ett_isis_hello_clv_unknown);
704 isis_dissect_clvs(tvb, pinfo, hello_tree, offset,
705 clv_ptp_hello_opts, len, id_length,
706 ett_isis_hello_clv_unknown);
711 * Name: isis_register_hello()
714 * Register our protocol sub-sets with protocol manager.
717 * int : protocol index for the ISIS protocol
723 isis_register_hello(int proto_isis) {
724 static hf_register_info hf[] = {
725 { &hf_isis_hello_circuit_reserved,
726 { "Circuit type ", "isis.hello.circuit_type",
727 FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }},
729 { &hf_isis_hello_source_id,
730 { "SystemID{ Sender of PDU } ", "isis.hello.source_id",
731 FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
733 { &hf_isis_hello_holding_timer,
734 { "Holding timer ", "isis.hello.holding_timer",
735 FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
737 { &hf_isis_hello_pdu_length,
738 { "PDU length ", "isis.hello.pdu_length",
739 FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
741 { &hf_isis_hello_priority_reserved,
742 { "Priority ", "isis.hello.priority",
743 FT_UINT8, BASE_DEC, NULL, ISIS_HELLO_P_RESERVED_MASK, "", HFILL }},
745 { &hf_isis_hello_lan_id,
746 { "SystemID{ Designated IS } ", "isis.hello.lan_id",
747 FT_BYTES, BASE_DEC, NULL, 0x0, "", HFILL }},
749 { &hf_isis_hello_local_circuit_id,
750 { "Local circuit ID ", "isis.hello.local_circuit_id",
751 FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
753 { &hf_isis_hello_clv_ipv4_int_addr,
754 { "IPv4 interface address ", "isis.hello.clv_ipv4_int_addr",
755 FT_IPv4, BASE_NONE, NULL, 0x0, "", HFILL }},
757 { &hf_isis_hello_clv_ipv6_int_addr,
758 { "IPv6 interface address ", "isis.hello.clv_ipv6_int_addr",
759 FT_IPv6, BASE_NONE, NULL, 0x0, "", HFILL }},
761 { &hf_isis_hello_clv_ptp_adj,
762 { "Point-to-point Adjacency ", "isis.hello.clv_ptp_adj",
763 FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
766 static gint *ett[] = {
768 &ett_isis_hello_clv_area_addr,
769 &ett_isis_hello_clv_is_neighbors,
770 &ett_isis_hello_clv_padding,
771 &ett_isis_hello_clv_unknown,
772 &ett_isis_hello_clv_nlpid,
773 &ett_isis_hello_clv_auth,
774 &ett_isis_hello_clv_ipv4_int_addr,
775 &ett_isis_hello_clv_ipv6_int_addr,
776 &ett_isis_hello_clv_ptp_adj,
777 &ett_isis_hello_clv_mt
780 proto_register_field_array(proto_isis, hf, array_length(hf));
781 proto_register_subtree_array(ett, array_length(ett));