2 * Routines for decoding isis hello packets and their CLVs
4 * $Id: packet-isis-hello.c,v 1.20 2001/07/02 01:41:25 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.
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 const value_string isis_hello_circuit_type_vals[] = {
72 { ISIS_HELLO_TYPE_RESERVED, "Reserved 0 (discard PDU)"},
73 { ISIS_HELLO_TYPE_LEVEL_1, "Level 1 only"},
74 { ISIS_HELLO_TYPE_LEVEL_2, "Level 2 only"},
75 { ISIS_HELLO_TYPE_LEVEL_12, "Level 1 and 2"},
79 * Predclare dissectors for use in clv dissection.
81 static void dissect_hello_padding_clv(tvbuff_t *tvb,
82 packet_info *pinfo, proto_tree *tree, int offset,
83 int id_length, int length);
84 static void dissect_hello_is_neighbors_clv(tvbuff_t *tvb,
85 packet_info *pinfo, proto_tree *tree, int offset,
86 int id_length, int length);
87 static void dissect_hello_ptp_adj_clv(tvbuff_t *tvb,
88 packet_info *pinfo, proto_tree *tree, int offset,
89 int id_length, int length);
90 static void dissect_hello_area_address_clv(tvbuff_t *tvb,
91 packet_info *pinfo, proto_tree *tree, int offset,
92 int id_length, int length);
93 static void dissect_hello_auth_clv(tvbuff_t *tvb,
94 packet_info *pinfo, proto_tree *tree, int offset,
95 int id_length, int length);
96 static void dissect_hello_ipv6_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_ip_int_addr_clv(tvbuff_t *tvb,
100 packet_info *pinfo, proto_tree *tree, int offset,
101 int id_length, int length);
102 static void dissect_hello_mt_clv(tvbuff_t *tvb,
103 packet_info *pinfo, proto_tree *tree, int offset,
104 int id_length, int length);
105 static void dissect_hello_nlpid_clv(tvbuff_t *tvb,
106 packet_info *pinfo, proto_tree *tree, int offset,
107 int id_length, int length);
110 static const isis_clv_handle_t clv_l1_hello_opts[] = {
112 ISIS_CLV_L1H_AREA_ADDRESS,
114 &ett_isis_hello_clv_area_addr,
115 dissect_hello_area_address_clv
118 ISIS_CLV_L1H_IS_NEIGHBORS,
120 &ett_isis_hello_clv_is_neighbors,
121 dissect_hello_is_neighbors_clv
124 ISIS_CLV_L1H_PADDING,
126 &ett_isis_hello_clv_padding,
127 dissect_hello_padding_clv
131 "Protocols Supported",
132 &ett_isis_hello_clv_nlpid,
133 dissect_hello_nlpid_clv
136 ISIS_CLV_L1H_IP_INTERFACE_ADDR,
137 "IP Interface address(es)",
138 &ett_isis_hello_clv_ipv4_int_addr,
139 dissect_hello_ip_int_addr_clv
142 ISIS_CLV_L1H_IPv6_INTERFACE_ADDR,
143 "IPv6 Interface address(es)",
144 &ett_isis_hello_clv_ipv6_int_addr,
145 dissect_hello_ipv6_int_addr_clv
148 ISIS_CLV_L1H_AUTHENTICATION_NS,
149 "Authentication(non spec)",
150 &ett_isis_hello_clv_auth,
151 dissect_hello_auth_clv
154 ISIS_CLV_L1H_AUTHENTICATION,
156 &ett_isis_hello_clv_auth,
157 dissect_hello_auth_clv
162 &ett_isis_hello_clv_mt,
173 static const isis_clv_handle_t clv_l2_hello_opts[] = {
175 ISIS_CLV_L2H_AREA_ADDRESS,
177 &ett_isis_hello_clv_area_addr,
178 dissect_hello_area_address_clv
181 ISIS_CLV_L2H_IS_NEIGHBORS,
183 &ett_isis_hello_clv_is_neighbors,
184 dissect_hello_is_neighbors_clv
187 ISIS_CLV_L2H_PADDING,
189 &ett_isis_hello_clv_padding,
190 dissect_hello_padding_clv
194 "Protocols Supported",
195 &ett_isis_hello_clv_nlpid,
196 dissect_hello_nlpid_clv
199 ISIS_CLV_L2H_IP_INTERFACE_ADDR,
200 "IP Interface address(es)",
201 &ett_isis_hello_clv_ipv4_int_addr,
202 dissect_hello_ip_int_addr_clv
205 ISIS_CLV_L2H_IPv6_INTERFACE_ADDR,
206 "IPv6 Interface address(es)",
207 &ett_isis_hello_clv_ipv6_int_addr,
208 dissect_hello_ipv6_int_addr_clv
211 ISIS_CLV_L2H_AUTHENTICATION_NS,
212 "Authentication(non spec)",
213 &ett_isis_hello_clv_auth,
214 dissect_hello_auth_clv
217 ISIS_CLV_L2H_AUTHENTICATION,
219 &ett_isis_hello_clv_auth,
220 dissect_hello_auth_clv
225 &ett_isis_hello_clv_mt,
236 static const isis_clv_handle_t clv_ptp_hello_opts[] = {
238 ISIS_CLV_PTP_AREA_ADDRESS,
240 &ett_isis_hello_clv_area_addr,
241 dissect_hello_area_address_clv
244 ISIS_CLV_PTP_PADDING,
246 &ett_isis_hello_clv_padding,
247 dissect_hello_padding_clv
251 "Protocols Supported",
252 &ett_isis_hello_clv_nlpid,
253 dissect_hello_nlpid_clv
256 ISIS_CLV_PTP_IP_INTERFACE_ADDR,
257 "IP Interface address(es)",
258 &ett_isis_hello_clv_ipv4_int_addr,
259 dissect_hello_ip_int_addr_clv
262 ISIS_CLV_PTP_IPv6_INTERFACE_ADDR,
263 "IPv6 Interface address(es)",
264 &ett_isis_hello_clv_ipv6_int_addr,
265 dissect_hello_ipv6_int_addr_clv
268 ISIS_CLV_PTP_AUTHENTICATION_NS,
269 "Authentication(non spec)",
270 &ett_isis_hello_clv_auth,
271 dissect_hello_auth_clv
274 ISIS_CLV_PTP_AUTHENTICATION,
276 &ett_isis_hello_clv_auth,
277 dissect_hello_auth_clv
281 "point-to-point Adjacency State",
282 &ett_isis_hello_clv_ptp_adj,
283 dissect_hello_ptp_adj_clv
288 &ett_isis_hello_clv_mt,
300 * Name: dissect_hello_nlpid_clv()
303 * Decode for a hello packets NLPID clv. Calls into the
307 * tvbuff_t * : tvbuffer for packet data
308 * packet_info * : info for current packet
309 * proto_tree * : proto tree to build on (may be null)
310 * int : current offset into packet data
311 * int : length of IDs in packet.
312 * int : length of this clv
315 * void, will modify proto_tree if not null.
318 dissect_hello_nlpid_clv(tvbuff_t *tvb,
319 packet_info *pinfo, proto_tree *tree, int offset,
320 int id_length, int length)
322 isis_dissect_nlpid_clv(tvb, pinfo, tree, offset, length);
326 * Name: dissect_hello_mt_clv()
329 * Decode for a hello packets Multi Topology clv. Calls into the
333 * tvbuff_t * : tvbuffer for packet data
334 * packet_info * : info for current packet
335 * proto_tree * : proto tree to build on (may be null)
336 * int : current offset into packet data
337 * int : length of IDs in packet.
338 * int : length of this clv
341 * void, will modify proto_tree if not null.
345 dissect_hello_mt_clv(tvbuff_t *tvb,
346 packet_info *pinfo, proto_tree *tree, int offset,
347 int id_length, int length)
349 isis_dissect_mt_clv(tvb, pinfo, tree, offset, length,
350 hf_isis_hello_clv_mt );
354 * Name: dissect_hello_ip_int_addr_clv()
357 * Decode for a hello packets ip interface addr clv. Calls into the
361 * tvbuff_t * : tvbuffer for packet data
362 * packet_info * : info for current packet
363 * proto_tree * : proto tree to build on (may be null)
364 * int : current offset into packet data
365 * int : length of IDs in packet.
366 * int : length of this clv
369 * void, will modify proto_tree if not null.
372 dissect_hello_ip_int_addr_clv(tvbuff_t *tvb,
373 packet_info *pinfo, proto_tree *tree, int offset,
374 int id_length, int length)
376 isis_dissect_ip_int_clv(tvb, pinfo, tree, offset, length,
377 hf_isis_hello_clv_ipv4_int_addr );
381 * Name: dissect_hello_ipv6_int_addr_clv()
384 * Decode for a hello packets ipv6 interface addr clv. Calls into the
388 * tvbuff_t * : tvbuffer for packet data
389 * packet_info * : info for current packet
390 * proto_tree * : proto tree to build on (may be null)
391 * int : current offset into packet data
392 * int : length of IDs in packet.
393 * int : length of this clv
396 * void, will modify proto_tree if not null.
399 dissect_hello_ipv6_int_addr_clv(tvbuff_t *tvb,
400 packet_info *pinfo, proto_tree *tree, int offset,
401 int id_length, int length)
403 isis_dissect_ipv6_int_clv(tvb, pinfo, tree, offset, length,
404 hf_isis_hello_clv_ipv6_int_addr );
408 * Name: dissect_hello_auth_clv()
411 * Decode for a hello packets authenticaion clv. Calls into the
412 * clv common one. An auth inside a hello packet is a perlink
416 * tvbuff_t * : tvbuffer for packet data
417 * packet_info * : info for current packet
418 * proto_tree * : proto tree to build on (may be null)
419 * int : current offset into packet data
420 * int : length of IDs in packet.
421 * int : length of this clv
424 * void, will modify proto_tree if not null.
427 dissect_hello_auth_clv(tvbuff_t *tvb,
428 packet_info *pinfo, proto_tree *tree, int offset,
429 int id_length, int length)
431 isis_dissect_authentication_clv(tvb, pinfo, tree, offset,
432 length, "authentication" );
436 * Name: dissect_hello_area_address_clv()
439 * Decode for a hello packets area address clv. Calls into the
443 * tvbuff_t * : tvbuffer for packet data
444 * packet_info * : info for current packet
445 * proto_tree * : proto tree to build on (may be null)
446 * int : current offset into packet data
447 * int : length of IDs in packet.
448 * int : length of this clv
451 * void, will modify proto_tree if not null.
454 dissect_hello_area_address_clv(tvbuff_t *tvb,
455 packet_info *pinfo, proto_tree *tree, int offset,
456 int id_length, int length)
458 isis_dissect_area_address_clv(tvb, pinfo, tree, offset, length);
464 dissect_hello_ptp_adj_clv(tvbuff_t *tvb,
465 packet_info *pinfo, proto_tree *tree, int offset,
466 int id_length, int length)
470 switch(tvb_get_guint8(tvb, offset)) {
472 strcpy(adj_state,"Up");
475 strcpy(adj_state,"Initializing");
478 strcpy(adj_state,"Down");
481 strcpy(adj_state,"<illegal value !!!>");
486 proto_tree_add_text ( tree, tvb, offset, 1,
487 "Adjacency State: %s", adj_state );
490 proto_tree_add_text ( tree, tvb, offset, 1,
491 "Adjacency State: %s", adj_state );
492 proto_tree_add_text ( tree, tvb, offset+1, 4,
493 "Extended Local Circuit ID: %u", tvb_get_ntohl(tvb, offset+1) );
496 proto_tree_add_text ( tree, tvb, offset, 1,
497 "Adjacency State: %s", adj_state );
498 proto_tree_add_text ( tree, tvb, offset+1, 4,
499 "Extended Local Circuit ID: %u", tvb_get_ntohl(tvb, offset+1) );
500 proto_tree_add_text ( tree, tvb, offset+5, 6,
501 "Neighbor System ID: %s", print_system_id( tvb_get_ptr(tvb, offset+5, 6), 6 ) );
504 proto_tree_add_text ( tree, tvb, offset, 1,
505 "Adjacency State: %s", adj_state );
506 proto_tree_add_text ( tree, tvb, offset+1, 4,
507 "Extended Local Circuit ID: %u", tvb_get_ntohl(tvb, offset+1) );
508 proto_tree_add_text ( tree, tvb, offset+5, 6,
509 "Neighbor System ID: %s", print_system_id( tvb_get_ptr(tvb, offset+5, 6), 6 ) );
510 proto_tree_add_text ( tree, tvb, offset+11, 4,
511 "Neighbor Extended Local Circuit ID: %u", tvb_get_ntohl(tvb, offset+11) );
514 isis_dissect_unknown(tvb, pinfo, tree, offset,
515 "malformed TLV (%d vs 1,5,11,15)", length );
521 * Name: isis_dissect_is_neighbors_clv()
524 * Take apart a IS neighbor packet. A neighbor is n 6 byte packets.
525 * (they tend to be an 802.3 MAC address, but its not required).
528 * tvbuff_t * : tvbuffer for packet data
529 * packet_info * : info for current packet
530 * proto_tree * : protocol display tree to fill out. May be NULL
531 * int : offset into packet data where we are.
532 * int : length of IDs in packet.
533 * int : length of clv we are decoding
536 * void, but we will add to proto tree if !NULL.
539 dissect_hello_is_neighbors_clv(tvbuff_t *tvb, packet_info *pinfo,
540 proto_tree *tree, int offset, int id_length, int length)
542 while ( length > 0 ) {
544 isis_dissect_unknown(tvb, pinfo, tree, offset,
545 "short is neighbor (%d vs 6)", length );
549 * Lets turn the area address into "standard" 0000.0000.etc
553 proto_tree_add_text ( tree, tvb, offset, 6,
554 "IS Neighbor: %s", print_system_id( tvb_get_ptr(tvb, offset, 6), 6 ) );
562 * Name: dissect_hello_padding_clv()
565 * Decode for a hello packet's padding clv. Padding does nothing,
569 * tvbuff_t * : tvbuffer for packet data
570 * packet_info * : info for current packet
571 * proto_tree * : proto tree to build on (may be null)
572 * int : current offset into packet data
573 * int : length of IDs in packet.
574 * int : length of this clv
580 dissect_hello_padding_clv(tvbuff_t *tvb, packet_info *pinfo,
581 proto_tree *tree, int offset, int id_length, int length)
583 /* nothing to do here! */
588 * Name: isis_dissect_isis_hello()
591 * This procedure rips apart the various types of ISIS hellos. L1H and
592 * L2H's are identical for the most part, while the PTP hello has
596 * tvbuff_t * : tvbuffer for packet data
597 * packet_info * : info for current packet
598 * proto_tree * : protocol display tree to add to. May be NULL.
599 * int offset : our offset into packet data.
600 * int : hello type, a la packet-isis.h ISIS_TYPE_* values
601 * int : header length of packet.
602 * int : length of IDs in packet.
605 * void, will modify proto_tree if not NULL.
608 isis_dissect_isis_hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
609 int offset, int hello_type, int header_length, int id_length)
612 proto_tree *hello_tree = NULL;
615 const guint8 *source_id;
617 const guint8 *lan_id;
619 if (!proto_is_protocol_enabled(proto_isis_hello)) {
620 dissect_data(tvb, offset, pinfo, tree);
625 ti = proto_tree_add_item(tree, proto_isis_hello, tvb,
626 offset, tvb_length_remaining(tvb, offset), FALSE);
627 hello_tree = proto_item_add_subtree(ti, ett_isis_hello);
628 octet = tvb_get_guint8(tvb, offset);
629 proto_tree_add_uint_format(hello_tree,
630 hf_isis_hello_circuit_reserved,
631 tvb, offset, 1, octet,
632 "Circuit type : %s, reserved(0x%02x == 0)",
633 val_to_str(octet&ISIS_HELLO_CTYPE_MASK,
634 isis_hello_circuit_type_vals,
636 octet&ISIS_HELLO_CT_RESERVED_MASK
642 source_id = tvb_get_ptr(tvb, offset, id_length);
643 proto_tree_add_bytes_format(hello_tree, hf_isis_hello_source_id, tvb,
644 offset, id_length, source_id,
645 "SystemID{ Sender of PDU } : %s",
646 print_system_id( source_id, id_length ) );
651 proto_tree_add_item(hello_tree, hf_isis_hello_holding_timer, tvb,
656 pdu_length = tvb_get_ntohs(tvb, offset);
658 proto_tree_add_uint(hello_tree, hf_isis_hello_pdu_length, tvb,
659 offset, 2, pdu_length);
663 if (hello_type == ISIS_TYPE_PTP_HELLO) {
665 proto_tree_add_item(hello_tree, hf_isis_hello_local_circuit_id, tvb,
672 octet = tvb_get_guint8(tvb, offset);
673 proto_tree_add_uint_format(hello_tree, hf_isis_hello_priority_reserved, tvb,
675 "Priority : %d, reserved(0x%02x == 0)",
676 octet&ISIS_HELLO_PRIORITY_MASK,
677 octet&ISIS_HELLO_P_RESERVED_MASK );
682 lan_id = tvb_get_ptr(tvb, offset, id_length+1);
683 proto_tree_add_bytes_format(hello_tree, hf_isis_hello_lan_id, tvb,
684 offset, id_length + 1, lan_id,
685 "SystemID{ Designated IS } : %s",
686 print_system_id( lan_id, id_length + 1 ) );
688 offset += id_length + 1;
692 len -= header_length;
694 isis_dissect_unknown(tvb, pinfo, tree, offset,
695 "Packet header length %d went beyond packet",
700 * Now, we need to decode our CLVs. We need to pass in
701 * our list of valid ones!
703 if (hello_type == ISIS_TYPE_L1_HELLO){
704 isis_dissect_clvs(tvb, pinfo, hello_tree, offset,
705 clv_l1_hello_opts, len, id_length,
706 ett_isis_hello_clv_unknown);
707 } else if (hello_type == ISIS_TYPE_L2_HELLO) {
708 isis_dissect_clvs(tvb, pinfo, hello_tree, offset,
709 clv_l2_hello_opts, len, id_length,
710 ett_isis_hello_clv_unknown);
712 isis_dissect_clvs(tvb, pinfo, hello_tree, offset,
713 clv_ptp_hello_opts, len, id_length,
714 ett_isis_hello_clv_unknown);
719 * Name: proto_register_isis_hello()
722 * Register our protocol sub-sets with protocol manager.
723 * NOTE: this procedure is autolinked by the makefile process that
733 proto_register_isis_hello(void) {
734 static hf_register_info hf[] = {
735 { &hf_isis_hello_circuit_reserved,
736 { "Circuit type ", "isis_hello.circuite_type",
737 FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }},
739 { &hf_isis_hello_source_id,
740 { "SystemID{ Sender of PDU } ", "isis_hello.source_id",
741 FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
743 { &hf_isis_hello_holding_timer,
744 { "Holding timer ", "isis_hello.holding_timer",
745 FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
747 { &hf_isis_hello_pdu_length,
748 { "PDU length ", "isis_hello.pdu_length",
749 FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
751 { &hf_isis_hello_priority_reserved,
752 { "Priority ", "isis_hello.priority",
753 FT_UINT8, BASE_DEC, NULL, ISIS_HELLO_P_RESERVED_MASK, "", HFILL }},
755 { &hf_isis_hello_lan_id,
756 { "SystemID{ Designated IS } ", "isis_hello.lan_id",
757 FT_BYTES, BASE_DEC, NULL, 0x0, "", HFILL }},
759 { &hf_isis_hello_local_circuit_id,
760 { "Local circuit ID ", "isis_hello.local_circuit_id",
761 FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
763 { &hf_isis_hello_clv_ipv4_int_addr,
764 { "IPv4 interface address ", "isis_hello.clv_ipv4_int_addr",
765 FT_IPv4, BASE_NONE, NULL, 0x0, "", HFILL }},
767 { &hf_isis_hello_clv_ipv6_int_addr,
768 { "IPv6 interface address ", "isis_hello.clv_ipv6_int_addr",
769 FT_IPv6, BASE_NONE, NULL, 0x0, "", HFILL }},
771 { &hf_isis_hello_clv_ptp_adj,
772 { "point-to-point Adjacency ", "isis_hello.clv_ptp_adj",
773 FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
776 static gint *ett[] = {
778 &ett_isis_hello_clv_area_addr,
779 &ett_isis_hello_clv_is_neighbors,
780 &ett_isis_hello_clv_padding,
781 &ett_isis_hello_clv_unknown,
782 &ett_isis_hello_clv_nlpid,
783 &ett_isis_hello_clv_auth,
784 &ett_isis_hello_clv_ipv4_int_addr,
785 &ett_isis_hello_clv_ipv6_int_addr,
786 &ett_isis_hello_clv_ptp_adj,
787 &ett_isis_hello_clv_mt
790 proto_isis_hello = proto_register_protocol("ISIS HELLO",
791 "ISIS HELLO", "isis_hello");
792 proto_register_field_array(proto_isis_hello, hf, array_length(hf));
793 proto_register_subtree_array(ett, array_length(ett));