2 * Routines for decoding isis hello packets and their CLVs
4 * $Id: packet-isis-hello.c,v 1.22 2001/11/26 04:52:50 hagbard 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.
32 #ifdef HAVE_SYS_TYPES_H
33 # include <sys/types.h>
40 #include "packet-osi.h"
41 #include "packet-isis.h"
42 #include "packet-isis-clv.h"
43 #include "packet-isis-hello.h"
46 static int proto_isis_hello = -1;
47 static int hf_isis_hello_circuit_reserved = -1;
48 static int hf_isis_hello_source_id = -1;
49 static int hf_isis_hello_holding_timer = -1;
50 static int hf_isis_hello_pdu_length = -1;
51 static int hf_isis_hello_priority_reserved = -1;
52 static int hf_isis_hello_lan_id = -1;
53 static int hf_isis_hello_local_circuit_id = -1;
54 static int hf_isis_hello_clv_ipv4_int_addr = -1;
55 static int hf_isis_hello_clv_ipv6_int_addr = -1;
56 static int hf_isis_hello_clv_ptp_adj = -1;
57 static int hf_isis_hello_clv_mt = -1;
59 static gint ett_isis_hello = -1;
60 static gint ett_isis_hello_clv_area_addr = -1;
61 static gint ett_isis_hello_clv_is_neighbors = -1;
62 static gint ett_isis_hello_clv_padding = -1;
63 static gint ett_isis_hello_clv_unknown = -1;
64 static gint ett_isis_hello_clv_nlpid = -1;
65 static gint ett_isis_hello_clv_auth = -1;
66 static gint ett_isis_hello_clv_ipv4_int_addr = -1;
67 static gint ett_isis_hello_clv_ipv6_int_addr = -1;
68 static gint ett_isis_hello_clv_ptp_adj = -1;
69 static gint ett_isis_hello_clv_mt = -1;
71 static dissector_handle_t data_handle;
73 static const value_string isis_hello_circuit_type_vals[] = {
74 { ISIS_HELLO_TYPE_RESERVED, "Reserved 0 (discard PDU)"},
75 { ISIS_HELLO_TYPE_LEVEL_1, "Level 1 only"},
76 { ISIS_HELLO_TYPE_LEVEL_2, "Level 2 only"},
77 { ISIS_HELLO_TYPE_LEVEL_12, "Level 1 and 2"},
81 * Predclare dissectors for use in clv dissection.
83 static void dissect_hello_padding_clv(tvbuff_t *tvb,
84 packet_info *pinfo, proto_tree *tree, int offset,
85 int id_length, int length);
86 static void dissect_hello_is_neighbors_clv(tvbuff_t *tvb,
87 packet_info *pinfo, proto_tree *tree, int offset,
88 int id_length, int length);
89 static void dissect_hello_ptp_adj_clv(tvbuff_t *tvb,
90 packet_info *pinfo, proto_tree *tree, int offset,
91 int id_length, int length);
92 static void dissect_hello_area_address_clv(tvbuff_t *tvb,
93 packet_info *pinfo, proto_tree *tree, int offset,
94 int id_length, int length);
95 static void dissect_hello_auth_clv(tvbuff_t *tvb,
96 packet_info *pinfo, proto_tree *tree, int offset,
97 int id_length, int length);
98 static void dissect_hello_ipv6_int_addr_clv(tvbuff_t *tvb,
99 packet_info *pinfo, proto_tree *tree, int offset,
100 int id_length, int length);
101 static void dissect_hello_ip_int_addr_clv(tvbuff_t *tvb,
102 packet_info *pinfo, proto_tree *tree, int offset,
103 int id_length, int length);
104 static void dissect_hello_mt_clv(tvbuff_t *tvb,
105 packet_info *pinfo, proto_tree *tree, int offset,
106 int id_length, int length);
107 static void dissect_hello_nlpid_clv(tvbuff_t *tvb,
108 packet_info *pinfo, proto_tree *tree, int offset,
109 int id_length, int length);
112 static const isis_clv_handle_t clv_l1_hello_opts[] = {
114 ISIS_CLV_L1H_AREA_ADDRESS,
116 &ett_isis_hello_clv_area_addr,
117 dissect_hello_area_address_clv
120 ISIS_CLV_L1H_IS_NEIGHBORS,
122 &ett_isis_hello_clv_is_neighbors,
123 dissect_hello_is_neighbors_clv
126 ISIS_CLV_L1H_PADDING,
128 &ett_isis_hello_clv_padding,
129 dissect_hello_padding_clv
133 "Protocols Supported",
134 &ett_isis_hello_clv_nlpid,
135 dissect_hello_nlpid_clv
138 ISIS_CLV_L1H_IP_INTERFACE_ADDR,
139 "IP Interface address(es)",
140 &ett_isis_hello_clv_ipv4_int_addr,
141 dissect_hello_ip_int_addr_clv
144 ISIS_CLV_L1H_IPv6_INTERFACE_ADDR,
145 "IPv6 Interface address(es)",
146 &ett_isis_hello_clv_ipv6_int_addr,
147 dissect_hello_ipv6_int_addr_clv
150 ISIS_CLV_L1H_AUTHENTICATION_NS,
151 "Authentication(non spec)",
152 &ett_isis_hello_clv_auth,
153 dissect_hello_auth_clv
156 ISIS_CLV_L1H_AUTHENTICATION,
158 &ett_isis_hello_clv_auth,
159 dissect_hello_auth_clv
164 &ett_isis_hello_clv_mt,
175 static const isis_clv_handle_t clv_l2_hello_opts[] = {
177 ISIS_CLV_L2H_AREA_ADDRESS,
179 &ett_isis_hello_clv_area_addr,
180 dissect_hello_area_address_clv
183 ISIS_CLV_L2H_IS_NEIGHBORS,
185 &ett_isis_hello_clv_is_neighbors,
186 dissect_hello_is_neighbors_clv
189 ISIS_CLV_L2H_PADDING,
191 &ett_isis_hello_clv_padding,
192 dissect_hello_padding_clv
196 "Protocols Supported",
197 &ett_isis_hello_clv_nlpid,
198 dissect_hello_nlpid_clv
201 ISIS_CLV_L2H_IP_INTERFACE_ADDR,
202 "IP Interface address(es)",
203 &ett_isis_hello_clv_ipv4_int_addr,
204 dissect_hello_ip_int_addr_clv
207 ISIS_CLV_L2H_IPv6_INTERFACE_ADDR,
208 "IPv6 Interface address(es)",
209 &ett_isis_hello_clv_ipv6_int_addr,
210 dissect_hello_ipv6_int_addr_clv
213 ISIS_CLV_L2H_AUTHENTICATION_NS,
214 "Authentication(non spec)",
215 &ett_isis_hello_clv_auth,
216 dissect_hello_auth_clv
219 ISIS_CLV_L2H_AUTHENTICATION,
221 &ett_isis_hello_clv_auth,
222 dissect_hello_auth_clv
227 &ett_isis_hello_clv_mt,
238 static const isis_clv_handle_t clv_ptp_hello_opts[] = {
240 ISIS_CLV_PTP_AREA_ADDRESS,
242 &ett_isis_hello_clv_area_addr,
243 dissect_hello_area_address_clv
246 ISIS_CLV_PTP_PADDING,
248 &ett_isis_hello_clv_padding,
249 dissect_hello_padding_clv
253 "Protocols Supported",
254 &ett_isis_hello_clv_nlpid,
255 dissect_hello_nlpid_clv
258 ISIS_CLV_PTP_IP_INTERFACE_ADDR,
259 "IP Interface address(es)",
260 &ett_isis_hello_clv_ipv4_int_addr,
261 dissect_hello_ip_int_addr_clv
264 ISIS_CLV_PTP_IPv6_INTERFACE_ADDR,
265 "IPv6 Interface address(es)",
266 &ett_isis_hello_clv_ipv6_int_addr,
267 dissect_hello_ipv6_int_addr_clv
270 ISIS_CLV_PTP_AUTHENTICATION_NS,
271 "Authentication(non spec)",
272 &ett_isis_hello_clv_auth,
273 dissect_hello_auth_clv
276 ISIS_CLV_PTP_AUTHENTICATION,
278 &ett_isis_hello_clv_auth,
279 dissect_hello_auth_clv
283 "point-to-point Adjacency State",
284 &ett_isis_hello_clv_ptp_adj,
285 dissect_hello_ptp_adj_clv
290 &ett_isis_hello_clv_mt,
302 * Name: dissect_hello_nlpid_clv()
305 * Decode for a hello packets NLPID clv. Calls into the
309 * tvbuff_t * : tvbuffer for packet data
310 * packet_info * : info for current packet
311 * proto_tree * : proto tree to build on (may be null)
312 * int : current offset into packet data
313 * int : length of IDs in packet.
314 * int : length of this clv
317 * void, will modify proto_tree if not null.
320 dissect_hello_nlpid_clv(tvbuff_t *tvb,
321 packet_info *pinfo, proto_tree *tree, int offset,
322 int id_length, int length)
324 isis_dissect_nlpid_clv(tvb, pinfo, tree, offset, length);
328 * Name: dissect_hello_mt_clv()
331 * Decode for a hello packets Multi Topology clv. Calls into the
335 * tvbuff_t * : tvbuffer for packet data
336 * packet_info * : info for current packet
337 * proto_tree * : proto tree to build on (may be null)
338 * int : current offset into packet data
339 * int : length of IDs in packet.
340 * int : length of this clv
343 * void, will modify proto_tree if not null.
347 dissect_hello_mt_clv(tvbuff_t *tvb,
348 packet_info *pinfo, proto_tree *tree, int offset,
349 int id_length, int length)
351 isis_dissect_mt_clv(tvb, pinfo, tree, offset, length,
352 hf_isis_hello_clv_mt );
356 * Name: dissect_hello_ip_int_addr_clv()
359 * Decode for a hello packets ip interface addr clv. Calls into the
363 * tvbuff_t * : tvbuffer for packet data
364 * packet_info * : info for current packet
365 * proto_tree * : proto tree to build on (may be null)
366 * int : current offset into packet data
367 * int : length of IDs in packet.
368 * int : length of this clv
371 * void, will modify proto_tree if not null.
374 dissect_hello_ip_int_addr_clv(tvbuff_t *tvb,
375 packet_info *pinfo, proto_tree *tree, int offset,
376 int id_length, int length)
378 isis_dissect_ip_int_clv(tvb, pinfo, tree, offset, length,
379 hf_isis_hello_clv_ipv4_int_addr );
383 * Name: dissect_hello_ipv6_int_addr_clv()
386 * Decode for a hello packets ipv6 interface addr clv. Calls into the
390 * tvbuff_t * : tvbuffer for packet data
391 * packet_info * : info for current packet
392 * proto_tree * : proto tree to build on (may be null)
393 * int : current offset into packet data
394 * int : length of IDs in packet.
395 * int : length of this clv
398 * void, will modify proto_tree if not null.
401 dissect_hello_ipv6_int_addr_clv(tvbuff_t *tvb,
402 packet_info *pinfo, proto_tree *tree, int offset,
403 int id_length, int length)
405 isis_dissect_ipv6_int_clv(tvb, pinfo, tree, offset, length,
406 hf_isis_hello_clv_ipv6_int_addr );
410 * Name: dissect_hello_auth_clv()
413 * Decode for a hello packets authenticaion clv. Calls into the
414 * clv common one. An auth inside a hello packet is a perlink
418 * tvbuff_t * : tvbuffer for packet data
419 * packet_info * : info for current packet
420 * proto_tree * : proto tree to build on (may be null)
421 * int : current offset into packet data
422 * int : length of IDs in packet.
423 * int : length of this clv
426 * void, will modify proto_tree if not null.
429 dissect_hello_auth_clv(tvbuff_t *tvb,
430 packet_info *pinfo, proto_tree *tree, int offset,
431 int id_length, int length)
433 isis_dissect_authentication_clv(tvb, pinfo, tree, offset,
434 length, "authentication" );
438 * Name: dissect_hello_area_address_clv()
441 * Decode for a hello packets area address clv. Calls into the
445 * tvbuff_t * : tvbuffer for packet data
446 * packet_info * : info for current packet
447 * proto_tree * : proto tree to build on (may be null)
448 * int : current offset into packet data
449 * int : length of IDs in packet.
450 * int : length of this clv
453 * void, will modify proto_tree if not null.
456 dissect_hello_area_address_clv(tvbuff_t *tvb,
457 packet_info *pinfo, proto_tree *tree, int offset,
458 int id_length, int length)
460 isis_dissect_area_address_clv(tvb, pinfo, tree, offset, length);
466 dissect_hello_ptp_adj_clv(tvbuff_t *tvb,
467 packet_info *pinfo, proto_tree *tree, int offset,
468 int id_length, int length)
472 switch(tvb_get_guint8(tvb, offset)) {
474 strcpy(adj_state,"Up");
477 strcpy(adj_state,"Initializing");
480 strcpy(adj_state,"Down");
483 strcpy(adj_state,"<illegal value !!!>");
488 proto_tree_add_text ( tree, tvb, offset, 1,
489 "Adjacency State: %s", adj_state );
492 proto_tree_add_text ( tree, tvb, offset, 1,
493 "Adjacency State: %s", adj_state );
494 proto_tree_add_text ( tree, tvb, offset+1, 4,
495 "Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+1) );
498 proto_tree_add_text ( tree, tvb, offset, 1,
499 "Adjacency State: %s", adj_state );
500 proto_tree_add_text ( tree, tvb, offset+1, 4,
501 "Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+1) );
502 proto_tree_add_text ( tree, tvb, offset+5, 6,
503 "Neighbor SystemID: %s", print_system_id( tvb_get_ptr(tvb, offset+5, 6), 6 ) );
506 proto_tree_add_text ( tree, tvb, offset, 1,
507 "Adjacency State: %s", adj_state );
508 proto_tree_add_text ( tree, tvb, offset+1, 4,
509 "Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+1) );
510 proto_tree_add_text ( tree, tvb, offset+5, 6,
511 "Neighbor SystemID: %s", print_system_id( tvb_get_ptr(tvb, offset+5, 6), 6 ) );
512 proto_tree_add_text ( tree, tvb, offset+11, 4,
513 "Neighbor Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+11) );
516 isis_dissect_unknown(tvb, pinfo, tree, offset,
517 "malformed TLV (%d vs 1,5,11,15)", length );
523 * Name: isis_dissect_is_neighbors_clv()
526 * Take apart a IS neighbor packet. A neighbor is n 6 byte packets.
527 * (they tend to be an 802.3 MAC address, but its not required).
530 * tvbuff_t * : tvbuffer for packet data
531 * packet_info * : info for current packet
532 * proto_tree * : protocol display tree to fill out. May be NULL
533 * int : offset into packet data where we are.
534 * int : length of IDs in packet.
535 * int : length of clv we are decoding
538 * void, but we will add to proto tree if !NULL.
541 dissect_hello_is_neighbors_clv(tvbuff_t *tvb, packet_info *pinfo,
542 proto_tree *tree, int offset, int id_length, int length)
544 while ( length > 0 ) {
546 isis_dissect_unknown(tvb, pinfo, tree, offset,
547 "short is neighbor (%d vs 6)", length );
551 * Lets turn the area address into "standard" 0000.0000.etc
555 proto_tree_add_text ( tree, tvb, offset, 6,
556 "IS Neighbor: %s", print_system_id( tvb_get_ptr(tvb, offset, 6), 6 ) );
564 * Name: dissect_hello_padding_clv()
567 * Decode for a hello packet's padding clv. Padding does nothing,
571 * tvbuff_t * : tvbuffer for packet data
572 * packet_info * : info for current packet
573 * proto_tree * : proto tree to build on (may be null)
574 * int : current offset into packet data
575 * int : length of IDs in packet.
576 * int : length of this clv
582 dissect_hello_padding_clv(tvbuff_t *tvb, packet_info *pinfo,
583 proto_tree *tree, int offset, int id_length, int length)
585 /* nothing to do here! */
590 * Name: isis_dissect_isis_hello()
593 * This procedure rips apart the various types of ISIS hellos. L1H and
594 * L2H's are identical for the most part, while the PTP hello has
598 * tvbuff_t * : tvbuffer for packet data
599 * packet_info * : info for current packet
600 * proto_tree * : protocol display tree to add to. May be NULL.
601 * int offset : our offset into packet data.
602 * int : hello type, a la packet-isis.h ISIS_TYPE_* values
603 * int : header length of packet.
604 * int : length of IDs in packet.
607 * void, will modify proto_tree if not NULL.
610 isis_dissect_isis_hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
611 int offset, int hello_type, int header_length, int id_length)
614 proto_tree *hello_tree = NULL;
617 const guint8 *source_id;
619 const guint8 *lan_id;
621 if (!proto_is_protocol_enabled(proto_isis_hello)) {
622 call_dissector(data_handle,tvb_new_subset(tvb, offset,-1,tvb_reported_length_remaining(tvb,offset)), pinfo, tree);
627 ti = proto_tree_add_item(tree, proto_isis_hello, tvb,
628 offset, tvb_length_remaining(tvb, offset), FALSE);
629 hello_tree = proto_item_add_subtree(ti, ett_isis_hello);
630 octet = tvb_get_guint8(tvb, offset);
631 proto_tree_add_uint_format(hello_tree,
632 hf_isis_hello_circuit_reserved,
633 tvb, offset, 1, octet,
634 "Circuit type : %s, reserved(0x%02x == 0)",
635 val_to_str(octet&ISIS_HELLO_CTYPE_MASK,
636 isis_hello_circuit_type_vals,
638 octet&ISIS_HELLO_CT_RESERVED_MASK
644 source_id = tvb_get_ptr(tvb, offset, id_length);
645 proto_tree_add_bytes_format(hello_tree, hf_isis_hello_source_id, tvb,
646 offset, id_length, source_id,
647 "SystemID{ Sender of PDU } : %s",
648 print_system_id( source_id, id_length ) );
653 proto_tree_add_item(hello_tree, hf_isis_hello_holding_timer, tvb,
658 pdu_length = tvb_get_ntohs(tvb, offset);
660 proto_tree_add_uint(hello_tree, hf_isis_hello_pdu_length, tvb,
661 offset, 2, pdu_length);
665 if (hello_type == ISIS_TYPE_PTP_HELLO) {
667 proto_tree_add_item(hello_tree, hf_isis_hello_local_circuit_id, tvb,
674 octet = tvb_get_guint8(tvb, offset);
675 proto_tree_add_uint_format(hello_tree, hf_isis_hello_priority_reserved, tvb,
677 "Priority : %d, reserved(0x%02x == 0)",
678 octet&ISIS_HELLO_PRIORITY_MASK,
679 octet&ISIS_HELLO_P_RESERVED_MASK );
684 lan_id = tvb_get_ptr(tvb, offset, id_length+1);
685 proto_tree_add_bytes_format(hello_tree, hf_isis_hello_lan_id, tvb,
686 offset, id_length + 1, lan_id,
687 "SystemID{ Designated IS } : %s",
688 print_system_id( lan_id, id_length + 1 ) );
690 offset += id_length + 1;
694 len -= header_length;
696 isis_dissect_unknown(tvb, pinfo, tree, offset,
697 "Packet header length %d went beyond packet",
702 * Now, we need to decode our CLVs. We need to pass in
703 * our list of valid ones!
705 if (hello_type == ISIS_TYPE_L1_HELLO){
706 isis_dissect_clvs(tvb, pinfo, hello_tree, offset,
707 clv_l1_hello_opts, len, id_length,
708 ett_isis_hello_clv_unknown);
709 } else if (hello_type == ISIS_TYPE_L2_HELLO) {
710 isis_dissect_clvs(tvb, pinfo, hello_tree, offset,
711 clv_l2_hello_opts, len, id_length,
712 ett_isis_hello_clv_unknown);
714 isis_dissect_clvs(tvb, pinfo, hello_tree, offset,
715 clv_ptp_hello_opts, len, id_length,
716 ett_isis_hello_clv_unknown);
721 * Name: proto_register_isis_hello()
724 * Register our protocol sub-sets with protocol manager.
725 * NOTE: this procedure is autolinked by the makefile process that
735 proto_register_isis_hello(void) {
736 static hf_register_info hf[] = {
737 { &hf_isis_hello_circuit_reserved,
738 { "Circuit type ", "isis_hello.circuite_type",
739 FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }},
741 { &hf_isis_hello_source_id,
742 { "SystemID{ Sender of PDU } ", "isis_hello.source_id",
743 FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
745 { &hf_isis_hello_holding_timer,
746 { "Holding timer ", "isis_hello.holding_timer",
747 FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
749 { &hf_isis_hello_pdu_length,
750 { "PDU length ", "isis_hello.pdu_length",
751 FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
753 { &hf_isis_hello_priority_reserved,
754 { "Priority ", "isis_hello.priority",
755 FT_UINT8, BASE_DEC, NULL, ISIS_HELLO_P_RESERVED_MASK, "", HFILL }},
757 { &hf_isis_hello_lan_id,
758 { "SystemID{ Designated IS } ", "isis_hello.lan_id",
759 FT_BYTES, BASE_DEC, NULL, 0x0, "", HFILL }},
761 { &hf_isis_hello_local_circuit_id,
762 { "Local circuit ID ", "isis_hello.local_circuit_id",
763 FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
765 { &hf_isis_hello_clv_ipv4_int_addr,
766 { "IPv4 interface address ", "isis_hello.clv_ipv4_int_addr",
767 FT_IPv4, BASE_NONE, NULL, 0x0, "", HFILL }},
769 { &hf_isis_hello_clv_ipv6_int_addr,
770 { "IPv6 interface address ", "isis_hello.clv_ipv6_int_addr",
771 FT_IPv6, BASE_NONE, NULL, 0x0, "", HFILL }},
773 { &hf_isis_hello_clv_ptp_adj,
774 { "point-to-point Adjacency ", "isis_hello.clv_ptp_adj",
775 FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
778 static gint *ett[] = {
780 &ett_isis_hello_clv_area_addr,
781 &ett_isis_hello_clv_is_neighbors,
782 &ett_isis_hello_clv_padding,
783 &ett_isis_hello_clv_unknown,
784 &ett_isis_hello_clv_nlpid,
785 &ett_isis_hello_clv_auth,
786 &ett_isis_hello_clv_ipv4_int_addr,
787 &ett_isis_hello_clv_ipv6_int_addr,
788 &ett_isis_hello_clv_ptp_adj,
789 &ett_isis_hello_clv_mt
792 proto_isis_hello = proto_register_protocol("ISIS HELLO",
793 "ISIS HELLO", "isis_hello");
794 proto_register_field_array(proto_isis_hello, hf, array_length(hf));
795 proto_register_subtree_array(ett, array_length(ett));
799 proto_reg_handoff_isis_hello(void){
800 data_handle = find_dissector("data");