2 * Routines for decoding isis hello packets and their CLVs
4 * $Id: packet-isis-hello.c,v 1.24 2001/12/26 21:37: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"
42 #include "epan/resolv.h"
45 static int hf_isis_hello_circuit_reserved = -1;
46 static int hf_isis_hello_source_id = -1;
47 static int hf_isis_hello_holding_timer = -1;
48 static int hf_isis_hello_pdu_length = -1;
49 static int hf_isis_hello_priority_reserved = -1;
50 static int hf_isis_hello_lan_id = -1;
51 static int hf_isis_hello_local_circuit_id = -1;
52 static int hf_isis_hello_clv_ipv4_int_addr = -1;
53 static int hf_isis_hello_clv_ipv6_int_addr = -1;
54 static int hf_isis_hello_clv_ptp_adj = -1;
55 static int hf_isis_hello_clv_mt = -1;
57 static gint ett_isis_hello = -1;
58 static gint ett_isis_hello_clv_area_addr = -1;
59 static gint ett_isis_hello_clv_is_neighbors = -1;
60 static gint ett_isis_hello_clv_padding = -1;
61 static gint ett_isis_hello_clv_unknown = -1;
62 static gint ett_isis_hello_clv_nlpid = -1;
63 static gint ett_isis_hello_clv_auth = -1;
64 static gint ett_isis_hello_clv_ipv4_int_addr = -1;
65 static gint ett_isis_hello_clv_ipv6_int_addr = -1;
66 static gint ett_isis_hello_clv_ptp_adj = -1;
67 static gint ett_isis_hello_clv_mt = -1;
69 static const value_string isis_hello_circuit_type_vals[] = {
70 { ISIS_HELLO_TYPE_RESERVED, "Reserved 0 (discard PDU)"},
71 { ISIS_HELLO_TYPE_LEVEL_1, "Level 1 only"},
72 { ISIS_HELLO_TYPE_LEVEL_2, "Level 2 only"},
73 { ISIS_HELLO_TYPE_LEVEL_12, "Level 1 and 2"},
77 * Predclare dissectors for use in clv dissection.
79 static void dissect_hello_padding_clv(tvbuff_t *tvb,
80 packet_info *pinfo, proto_tree *tree, int offset,
81 int id_length, int length);
82 static void dissect_hello_is_neighbors_clv(tvbuff_t *tvb,
83 packet_info *pinfo, proto_tree *tree, int offset,
84 int id_length, int length);
85 static void dissect_hello_ptp_adj_clv(tvbuff_t *tvb,
86 packet_info *pinfo, proto_tree *tree, int offset,
87 int id_length, int length);
88 static void dissect_hello_area_address_clv(tvbuff_t *tvb,
89 packet_info *pinfo, proto_tree *tree, int offset,
90 int id_length, int length);
91 static void dissect_hello_auth_clv(tvbuff_t *tvb,
92 packet_info *pinfo, proto_tree *tree, int offset,
93 int id_length, int length);
94 static void dissect_hello_ipv6_int_addr_clv(tvbuff_t *tvb,
95 packet_info *pinfo, proto_tree *tree, int offset,
96 int id_length, int length);
97 static void dissect_hello_ip_int_addr_clv(tvbuff_t *tvb,
98 packet_info *pinfo, proto_tree *tree, int offset,
99 int id_length, int length);
100 static void dissect_hello_mt_clv(tvbuff_t *tvb,
101 packet_info *pinfo, proto_tree *tree, int offset,
102 int id_length, int length);
103 static void dissect_hello_nlpid_clv(tvbuff_t *tvb,
104 packet_info *pinfo, proto_tree *tree, int offset,
105 int id_length, int length);
108 static const isis_clv_handle_t clv_l1_hello_opts[] = {
110 ISIS_CLV_L1H_AREA_ADDRESS,
112 &ett_isis_hello_clv_area_addr,
113 dissect_hello_area_address_clv
116 ISIS_CLV_L1H_IS_NEIGHBORS,
118 &ett_isis_hello_clv_is_neighbors,
119 dissect_hello_is_neighbors_clv
122 ISIS_CLV_L1H_PADDING,
124 &ett_isis_hello_clv_padding,
125 dissect_hello_padding_clv
129 "Protocols Supported",
130 &ett_isis_hello_clv_nlpid,
131 dissect_hello_nlpid_clv
134 ISIS_CLV_L1H_IP_INTERFACE_ADDR,
135 "IP Interface address(es)",
136 &ett_isis_hello_clv_ipv4_int_addr,
137 dissect_hello_ip_int_addr_clv
140 ISIS_CLV_L1H_IPv6_INTERFACE_ADDR,
141 "IPv6 Interface address(es)",
142 &ett_isis_hello_clv_ipv6_int_addr,
143 dissect_hello_ipv6_int_addr_clv
146 ISIS_CLV_L1H_AUTHENTICATION_NS,
147 "Authentication(non spec)",
148 &ett_isis_hello_clv_auth,
149 dissect_hello_auth_clv
152 ISIS_CLV_L1H_AUTHENTICATION,
154 &ett_isis_hello_clv_auth,
155 dissect_hello_auth_clv
160 &ett_isis_hello_clv_mt,
171 static const isis_clv_handle_t clv_l2_hello_opts[] = {
173 ISIS_CLV_L2H_AREA_ADDRESS,
175 &ett_isis_hello_clv_area_addr,
176 dissect_hello_area_address_clv
179 ISIS_CLV_L2H_IS_NEIGHBORS,
181 &ett_isis_hello_clv_is_neighbors,
182 dissect_hello_is_neighbors_clv
185 ISIS_CLV_L2H_PADDING,
187 &ett_isis_hello_clv_padding,
188 dissect_hello_padding_clv
192 "Protocols Supported",
193 &ett_isis_hello_clv_nlpid,
194 dissect_hello_nlpid_clv
197 ISIS_CLV_L2H_IP_INTERFACE_ADDR,
198 "IP Interface address(es)",
199 &ett_isis_hello_clv_ipv4_int_addr,
200 dissect_hello_ip_int_addr_clv
203 ISIS_CLV_L2H_IPv6_INTERFACE_ADDR,
204 "IPv6 Interface address(es)",
205 &ett_isis_hello_clv_ipv6_int_addr,
206 dissect_hello_ipv6_int_addr_clv
209 ISIS_CLV_L2H_AUTHENTICATION_NS,
210 "Authentication(non spec)",
211 &ett_isis_hello_clv_auth,
212 dissect_hello_auth_clv
215 ISIS_CLV_L2H_AUTHENTICATION,
217 &ett_isis_hello_clv_auth,
218 dissect_hello_auth_clv
223 &ett_isis_hello_clv_mt,
234 static const isis_clv_handle_t clv_ptp_hello_opts[] = {
236 ISIS_CLV_PTP_AREA_ADDRESS,
238 &ett_isis_hello_clv_area_addr,
239 dissect_hello_area_address_clv
242 ISIS_CLV_PTP_PADDING,
244 &ett_isis_hello_clv_padding,
245 dissect_hello_padding_clv
249 "Protocols Supported",
250 &ett_isis_hello_clv_nlpid,
251 dissect_hello_nlpid_clv
254 ISIS_CLV_PTP_IP_INTERFACE_ADDR,
255 "IP Interface address(es)",
256 &ett_isis_hello_clv_ipv4_int_addr,
257 dissect_hello_ip_int_addr_clv
260 ISIS_CLV_PTP_IPv6_INTERFACE_ADDR,
261 "IPv6 Interface address(es)",
262 &ett_isis_hello_clv_ipv6_int_addr,
263 dissect_hello_ipv6_int_addr_clv
266 ISIS_CLV_PTP_AUTHENTICATION_NS,
267 "Authentication(non spec)",
268 &ett_isis_hello_clv_auth,
269 dissect_hello_auth_clv
272 ISIS_CLV_PTP_AUTHENTICATION,
274 &ett_isis_hello_clv_auth,
275 dissect_hello_auth_clv
279 "Point-to-point Adjacency State",
280 &ett_isis_hello_clv_ptp_adj,
281 dissect_hello_ptp_adj_clv
286 &ett_isis_hello_clv_mt,
298 * Name: dissect_hello_nlpid_clv()
301 * Decode for a hello packets NLPID clv. Calls into the
305 * tvbuff_t * : tvbuffer for packet data
306 * packet_info * : info for current packet
307 * proto_tree * : proto tree to build on (may be null)
308 * int : current offset into packet data
309 * int : length of IDs in packet.
310 * int : length of this clv
313 * void, will modify proto_tree if not null.
316 dissect_hello_nlpid_clv(tvbuff_t *tvb,
317 packet_info *pinfo, proto_tree *tree, int offset,
318 int id_length, int length)
320 isis_dissect_nlpid_clv(tvb, pinfo, tree, offset, length);
324 * Name: dissect_hello_mt_clv()
327 * Decode for a hello packets Multi Topology clv. Calls into the
331 * tvbuff_t * : tvbuffer for packet data
332 * packet_info * : info for current packet
333 * proto_tree * : proto tree to build on (may be null)
334 * int : current offset into packet data
335 * int : length of IDs in packet.
336 * int : length of this clv
339 * void, will modify proto_tree if not null.
343 dissect_hello_mt_clv(tvbuff_t *tvb,
344 packet_info *pinfo, proto_tree *tree, int offset,
345 int id_length, int length)
347 isis_dissect_mt_clv(tvb, pinfo, tree, offset, length,
348 hf_isis_hello_clv_mt );
352 * Name: dissect_hello_ip_int_addr_clv()
355 * Decode for a hello packets ip interface addr clv. Calls into the
359 * tvbuff_t * : tvbuffer for packet data
360 * packet_info * : info for current packet
361 * proto_tree * : proto tree to build on (may be null)
362 * int : current offset into packet data
363 * int : length of IDs in packet.
364 * int : length of this clv
367 * void, will modify proto_tree if not null.
370 dissect_hello_ip_int_addr_clv(tvbuff_t *tvb,
371 packet_info *pinfo, proto_tree *tree, int offset,
372 int id_length, int length)
374 isis_dissect_ip_int_clv(tvb, pinfo, tree, offset, length,
375 hf_isis_hello_clv_ipv4_int_addr );
379 * Name: dissect_hello_ipv6_int_addr_clv()
382 * Decode for a hello packets ipv6 interface addr clv. Calls into the
386 * tvbuff_t * : tvbuffer for packet data
387 * packet_info * : info for current packet
388 * proto_tree * : proto tree to build on (may be null)
389 * int : current offset into packet data
390 * int : length of IDs in packet.
391 * int : length of this clv
394 * void, will modify proto_tree if not null.
397 dissect_hello_ipv6_int_addr_clv(tvbuff_t *tvb,
398 packet_info *pinfo, proto_tree *tree, int offset,
399 int id_length, int length)
401 isis_dissect_ipv6_int_clv(tvb, pinfo, tree, offset, length,
402 hf_isis_hello_clv_ipv6_int_addr );
406 * Name: dissect_hello_auth_clv()
409 * Decode for a hello packets authenticaion clv. Calls into the
410 * clv common one. An auth inside a hello packet is a perlink
414 * tvbuff_t * : tvbuffer for packet data
415 * packet_info * : info for current packet
416 * proto_tree * : proto tree to build on (may be null)
417 * int : current offset into packet data
418 * int : length of IDs in packet.
419 * int : length of this clv
422 * void, will modify proto_tree if not null.
425 dissect_hello_auth_clv(tvbuff_t *tvb,
426 packet_info *pinfo, proto_tree *tree, int offset,
427 int id_length, int length)
429 isis_dissect_authentication_clv(tvb, pinfo, tree, offset,
430 length, "authentication" );
434 * Name: dissect_hello_area_address_clv()
437 * Decode for a hello packets area address clv. Calls into the
441 * tvbuff_t * : tvbuffer for packet data
442 * packet_info * : info for current packet
443 * proto_tree * : proto tree to build on (may be null)
444 * int : current offset into packet data
445 * int : length of IDs in packet.
446 * int : length of this clv
449 * void, will modify proto_tree if not null.
452 dissect_hello_area_address_clv(tvbuff_t *tvb,
453 packet_info *pinfo, proto_tree *tree, int offset,
454 int id_length, int length)
456 isis_dissect_area_address_clv(tvb, pinfo, tree, offset, length);
462 dissect_hello_ptp_adj_clv(tvbuff_t *tvb,
463 packet_info *pinfo, proto_tree *tree, int offset,
464 int id_length, int length)
468 switch(tvb_get_guint8(tvb, offset)) {
470 strcpy(adj_state,"Up");
473 strcpy(adj_state,"Initializing");
476 strcpy(adj_state,"Down");
479 strcpy(adj_state,"<illegal value !!!>");
484 proto_tree_add_text ( tree, tvb, offset, 1,
485 "Adjacency State: %s", adj_state );
488 proto_tree_add_text ( tree, tvb, offset, 1,
489 "Adjacency State: %s", adj_state );
490 proto_tree_add_text ( tree, tvb, offset+1, 4,
491 "Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+1) );
494 proto_tree_add_text ( tree, tvb, offset, 1,
495 "Adjacency State: %s", adj_state );
496 proto_tree_add_text ( tree, tvb, offset+1, 4,
497 "Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+1) );
498 proto_tree_add_text ( tree, tvb, offset+5, 6,
499 "Neighbor SystemID: %s", print_system_id( tvb_get_ptr(tvb, offset+5, 6), 6 ) );
502 proto_tree_add_text ( tree, tvb, offset, 1,
503 "Adjacency State: %s", adj_state );
504 proto_tree_add_text ( tree, tvb, offset+1, 4,
505 "Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+1) );
506 proto_tree_add_text ( tree, tvb, offset+5, 6,
507 "Neighbor SystemID: %s", print_system_id( tvb_get_ptr(tvb, offset+5, 6), 6 ) );
508 proto_tree_add_text ( tree, tvb, offset+11, 4,
509 "Neighbor Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+11) );
512 isis_dissect_unknown(tvb, pinfo, tree, offset,
513 "malformed TLV (%d vs 1,5,11,15)", length );
519 * Name: isis_dissect_is_neighbors_clv()
522 * Take apart a IS neighbor packet. A neighbor is n 6 byte packets.
523 * (they tend to be an 802.3 MAC address, but its not required).
526 * tvbuff_t * : tvbuffer for packet data
527 * packet_info * : info for current packet
528 * proto_tree * : protocol display tree to fill out. May be NULL
529 * int : offset into packet data where we are.
530 * int : length of IDs in packet.
531 * int : length of clv we are decoding
534 * void, but we will add to proto tree if !NULL.
537 dissect_hello_is_neighbors_clv(tvbuff_t *tvb, packet_info *pinfo,
538 proto_tree *tree, int offset, int id_length, int length)
540 while ( length > 0 ) {
542 isis_dissect_unknown(tvb, pinfo, tree, offset,
543 "short is neighbor (%d vs 6)", length );
547 * Lets turn the area address into "standard" 0000.0000.etc
551 proto_tree_add_text ( tree, tvb, offset, 6,
552 "IS Neighbor: %s", get_ether_name( tvb_get_ptr(tvb, offset, 6)) );
560 * Name: dissect_hello_padding_clv()
563 * Decode for a hello packet's padding clv. Padding does nothing,
567 * tvbuff_t * : tvbuffer for packet data
568 * packet_info * : info for current packet
569 * proto_tree * : proto tree to build on (may be null)
570 * int : current offset into packet data
571 * int : length of IDs in packet.
572 * int : length of this clv
578 dissect_hello_padding_clv(tvbuff_t *tvb, packet_info *pinfo,
579 proto_tree *tree, int offset, int id_length, int length)
581 /* nothing to do here! */
586 * Name: isis_dissect_isis_hello()
589 * This procedure rips apart the various types of ISIS hellos. L1H and
590 * L2H's are identical for the most part, while the PTP hello has
594 * tvbuff_t * : tvbuffer for packet data
595 * packet_info * : info for current packet
596 * proto_tree * : protocol display tree to add to. May be NULL.
597 * int offset : our offset into packet data.
598 * int : hello type, a la packet-isis.h ISIS_TYPE_* values
599 * int : header length of packet.
600 * int : length of IDs in packet.
603 * void, will modify proto_tree if not NULL.
606 isis_dissect_isis_hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
607 int offset, int hello_type, int header_length, int id_length)
610 proto_tree *hello_tree = NULL;
613 const guint8 *source_id;
615 const guint8 *lan_id;
618 ti = proto_tree_add_text(tree, tvb, offset,
619 tvb_length_remaining(tvb, offset), "ISIS HELLO");
620 hello_tree = proto_item_add_subtree(ti, ett_isis_hello);
621 octet = tvb_get_guint8(tvb, offset);
622 proto_tree_add_uint_format(hello_tree,
623 hf_isis_hello_circuit_reserved,
624 tvb, offset, 1, octet,
625 "Circuit type : %s, reserved(0x%02x == 0)",
626 val_to_str(octet&ISIS_HELLO_CTYPE_MASK,
627 isis_hello_circuit_type_vals,
629 octet&ISIS_HELLO_CT_RESERVED_MASK
635 source_id = tvb_get_ptr(tvb, offset, id_length);
636 proto_tree_add_bytes_format(hello_tree, hf_isis_hello_source_id, tvb,
637 offset, id_length, source_id,
638 "SystemID{ Sender of PDU } : %s",
639 print_system_id( source_id, id_length ) );
644 proto_tree_add_item(hello_tree, hf_isis_hello_holding_timer, tvb,
649 pdu_length = tvb_get_ntohs(tvb, offset);
651 proto_tree_add_uint(hello_tree, hf_isis_hello_pdu_length, tvb,
652 offset, 2, pdu_length);
656 if (hello_type == ISIS_TYPE_PTP_HELLO) {
658 proto_tree_add_item(hello_tree, hf_isis_hello_local_circuit_id, tvb,
665 octet = tvb_get_guint8(tvb, offset);
666 proto_tree_add_uint_format(hello_tree, hf_isis_hello_priority_reserved, tvb,
668 "Priority : %d, reserved(0x%02x == 0)",
669 octet&ISIS_HELLO_PRIORITY_MASK,
670 octet&ISIS_HELLO_P_RESERVED_MASK );
675 lan_id = tvb_get_ptr(tvb, offset, id_length+1);
676 proto_tree_add_bytes_format(hello_tree, hf_isis_hello_lan_id, tvb,
677 offset, id_length + 1, lan_id,
678 "SystemID{ Designated IS } : %s",
679 print_system_id( lan_id, id_length + 1 ) );
681 offset += id_length + 1;
685 len -= header_length;
687 isis_dissect_unknown(tvb, pinfo, tree, offset,
688 "Packet header length %d went beyond packet",
693 * Now, we need to decode our CLVs. We need to pass in
694 * our list of valid ones!
696 if (hello_type == ISIS_TYPE_L1_HELLO){
697 isis_dissect_clvs(tvb, pinfo, hello_tree, offset,
698 clv_l1_hello_opts, len, id_length,
699 ett_isis_hello_clv_unknown);
700 } else if (hello_type == ISIS_TYPE_L2_HELLO) {
701 isis_dissect_clvs(tvb, pinfo, hello_tree, offset,
702 clv_l2_hello_opts, len, id_length,
703 ett_isis_hello_clv_unknown);
705 isis_dissect_clvs(tvb, pinfo, hello_tree, offset,
706 clv_ptp_hello_opts, len, id_length,
707 ett_isis_hello_clv_unknown);
712 * Name: isis_register_hello()
715 * Register our protocol sub-sets with protocol manager.
718 * int : protocol index for the ISIS protocol
724 isis_register_hello(int proto_isis) {
725 static hf_register_info hf[] = {
726 { &hf_isis_hello_circuit_reserved,
727 { "Circuit type ", "isis.hello.circuit_type",
728 FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }},
730 { &hf_isis_hello_source_id,
731 { "SystemID{ Sender of PDU } ", "isis.hello.source_id",
732 FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
734 { &hf_isis_hello_holding_timer,
735 { "Holding timer ", "isis.hello.holding_timer",
736 FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
738 { &hf_isis_hello_pdu_length,
739 { "PDU length ", "isis.hello.pdu_length",
740 FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
742 { &hf_isis_hello_priority_reserved,
743 { "Priority ", "isis.hello.priority",
744 FT_UINT8, BASE_DEC, NULL, ISIS_HELLO_P_RESERVED_MASK, "", HFILL }},
746 { &hf_isis_hello_lan_id,
747 { "SystemID{ Designated IS } ", "isis.hello.lan_id",
748 FT_BYTES, BASE_DEC, NULL, 0x0, "", HFILL }},
750 { &hf_isis_hello_local_circuit_id,
751 { "Local circuit ID ", "isis.hello.local_circuit_id",
752 FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
754 { &hf_isis_hello_clv_ipv4_int_addr,
755 { "IPv4 interface address ", "isis.hello.clv_ipv4_int_addr",
756 FT_IPv4, BASE_NONE, NULL, 0x0, "", HFILL }},
758 { &hf_isis_hello_clv_ipv6_int_addr,
759 { "IPv6 interface address ", "isis.hello.clv_ipv6_int_addr",
760 FT_IPv6, BASE_NONE, NULL, 0x0, "", HFILL }},
762 { &hf_isis_hello_clv_ptp_adj,
763 { "Point-to-point Adjacency ", "isis.hello.clv_ptp_adj",
764 FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
767 static gint *ett[] = {
769 &ett_isis_hello_clv_area_addr,
770 &ett_isis_hello_clv_is_neighbors,
771 &ett_isis_hello_clv_padding,
772 &ett_isis_hello_clv_unknown,
773 &ett_isis_hello_clv_nlpid,
774 &ett_isis_hello_clv_auth,
775 &ett_isis_hello_clv_ipv4_int_addr,
776 &ett_isis_hello_clv_ipv6_int_addr,
777 &ett_isis_hello_clv_ptp_adj,
778 &ett_isis_hello_clv_mt
781 proto_register_field_array(proto_isis, hf, array_length(hf));
782 proto_register_subtree_array(ett, array_length(ett));