2 * Routines for decoding isis lsp 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
34 #include <epan/ipv4.h>
35 #include <epan/packet.h>
36 #include "packet-osi.h"
37 #include "packet-ipv6.h"
38 #include "packet-isis.h"
39 #include "packet-isis-clv.h"
40 #include "packet-isis-lsp.h"
41 #include <epan/addr_resolv.h>
42 #include <epan/addr_and_mask.h>
43 #include <epan/expert.h>
46 static int hf_isis_lsp_pdu_length = -1;
47 static int hf_isis_lsp_remaining_life = -1;
48 static int hf_isis_lsp_sequence_number = -1;
49 static int hf_isis_lsp_lsp_id = -1;
50 static int hf_isis_lsp_hostname = -1;
51 static int hf_isis_lsp_checksum = -1;
52 static int hf_isis_lsp_checksum_bad = -1;
53 static int hf_isis_lsp_checksum_good = -1;
54 static int hf_isis_lsp_clv_ipv4_int_addr = -1;
55 static int hf_isis_lsp_clv_ipv6_int_addr = -1;
56 static int hf_isis_lsp_clv_te_router_id = -1;
57 static int hf_isis_lsp_clv_mt = -1;
58 static int hf_isis_lsp_p = -1;
59 static int hf_isis_lsp_att = -1;
60 static int hf_isis_lsp_hippity = -1;
61 static int hf_isis_lsp_is_type = -1;
63 static gint ett_isis_lsp = -1;
64 static gint ett_isis_lsp_info = -1;
65 static gint ett_isis_lsp_att = -1;
66 static gint ett_isis_lsp_cksum = -1;
67 static gint ett_isis_lsp_clv_area_addr = -1;
68 static gint ett_isis_lsp_clv_is_neighbors = -1;
69 static gint ett_isis_lsp_clv_ext_is_reachability = -1; /* CLV 22 */
70 static gint ett_isis_lsp_part_of_clv_ext_is_reachability = -1;
71 static gint ett_isis_lsp_subclv_admin_group = -1;
72 static gint ett_isis_lsp_subclv_unrsv_bw = -1;
73 static gint ett_isis_lsp_clv_unknown = -1;
74 static gint ett_isis_lsp_clv_partition_dis = -1;
75 static gint ett_isis_lsp_clv_prefix_neighbors = -1;
76 static gint ett_isis_lsp_clv_nlpid = -1;
77 static gint ett_isis_lsp_clv_hostname = -1;
78 static gint ett_isis_lsp_clv_te_router_id = -1;
79 static gint ett_isis_lsp_clv_authentication = -1;
80 static gint ett_isis_lsp_clv_ip_authentication = -1;
81 static gint ett_isis_lsp_clv_ipv4_int_addr = -1;
82 static gint ett_isis_lsp_clv_ipv6_int_addr = -1; /* CLV 232 */
83 static gint ett_isis_lsp_clv_ip_reachability = -1;
84 static gint ett_isis_lsp_clv_ip_reach_subclv = -1;
85 static gint ett_isis_lsp_clv_ext_ip_reachability = -1; /* CLV 135 */
86 static gint ett_isis_lsp_part_of_clv_ext_ip_reachability = -1;
87 static gint ett_isis_lsp_clv_ipv6_reachability = -1; /* CLV 236 */
88 static gint ett_isis_lsp_part_of_clv_ipv6_reachability = -1;
89 static gint ett_isis_lsp_clv_mt = -1;
90 static gint ett_isis_lsp_clv_mt_is = -1;
91 static gint ett_isis_lsp_part_of_clv_mt_is = -1;
92 static gint ett_isis_lsp_clv_mt_reachable_IPv4_prefx = -1; /* CLV 235 */
93 static gint ett_isis_lsp_clv_mt_reachable_IPv6_prefx = -1; /* CLV 237 */
95 static const value_string isis_lsp_istype_vals[] = {
96 { ISIS_LSP_TYPE_UNUSED0, "Unused 0x0 (invalid)"},
97 { ISIS_LSP_TYPE_LEVEL_1, "Level 1"},
98 { ISIS_LSP_TYPE_UNUSED2, "Unused 0x2 (invalid)"},
99 { ISIS_LSP_TYPE_LEVEL_2, "Level 2"},
104 * Predclare dissectors for use in clv dissection.
106 static void dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb,
107 proto_tree *tree, int offset, int id_length, int length);
108 static void dissect_lsp_partition_dis_clv(tvbuff_t *tvb,
109 proto_tree *tree, int offset, int id_length, int length);
110 static void dissect_lsp_mt_is_reachability_clv(tvbuff_t *tvb,
111 proto_tree *tree, int offset, int id_length, int length);
112 static void dissect_lsp_ext_is_reachability_clv(tvbuff_t *tvb,
113 proto_tree *tree, int offset, int id_length, int length);
114 static void dissect_lsp_l2_is_neighbors_clv(tvbuff_t *tvb,
115 proto_tree *tree, int offset, int id_length, int length);
116 static void dissect_lsp_l1_es_neighbors_clv(tvbuff_t *tvb,
117 proto_tree *tree, int offset, int id_length, int length);
118 static void dissect_lsp_l1_is_neighbors_clv(tvbuff_t *tvb,
119 proto_tree *tree, int offset, int id_length, int length);
120 static void dissect_lsp_area_address_clv(tvbuff_t *tvb,
121 proto_tree *tree, int offset, int id_length, int length);
122 static void dissect_lsp_authentication_clv(tvbuff_t *tvb,
123 proto_tree *tree, int offset, int id_length, int length);
124 static void dissect_lsp_ip_authentication_clv(tvbuff_t *tvb,
125 proto_tree *tree, int offset, int id_length, int length);
126 static void dissect_lsp_ipv6_int_addr_clv(tvbuff_t *tvb,
127 proto_tree *tree, int offset, int id_length, int length);
128 static void dissect_lsp_ip_int_addr_clv(tvbuff_t *tvb,
129 proto_tree *tree, int offset, int id_length, int length);
130 static void dissect_lsp_te_router_id_clv(tvbuff_t *tvb,
131 proto_tree *tree, int offset, int id_length, int length);
132 static void dissect_lsp_hostname_clv(tvbuff_t *tvb,
133 proto_tree *tree, int offset, int id_length, int length);
134 static void dissect_lsp_mt_clv(tvbuff_t *tvb,
135 proto_tree *tree, int offset, int id_length, int length);
136 static void dissect_lsp_nlpid_clv(tvbuff_t *tvb,
137 proto_tree *tree, int offset, int id_length, int length);
138 static void dissect_lsp_ipv6_reachability_clv(tvbuff_t *tvb,
139 proto_tree *tree, int offset, int id_length, int length);
140 static void dissect_lsp_ext_ip_reachability_clv(tvbuff_t *tvb,
141 proto_tree *tree, int offset, int id_length, int length);
142 static void dissect_lsp_ip_reachability_clv(tvbuff_t *tvb,
143 proto_tree *tree, int offset, int id_length, int length);
144 static void dissect_ipreach_subclv(tvbuff_t *tvb,
145 proto_tree *tree, int offset, int clv_code, int clv_len);
146 static void dissect_lsp_mt_reachable_IPv4_prefx_clv(tvbuff_t *tvb,
147 proto_tree *tree, int offset, int id_length, int length);
148 static void dissect_lsp_mt_reachable_IPv6_prefx_clv(tvbuff_t *tvb,
149 proto_tree *tree, int offset, int id_length, int length);
152 static const isis_clv_handle_t clv_l1_lsp_opts[] = {
154 ISIS_CLV_AREA_ADDRESS,
156 &ett_isis_lsp_clv_area_addr,
157 dissect_lsp_area_address_clv
162 &ett_isis_lsp_clv_is_neighbors,
163 dissect_lsp_l1_is_neighbors_clv
166 ISIS_CLV_ES_NEIGHBORS,
168 &ett_isis_lsp_clv_is_neighbors,
169 dissect_lsp_l1_es_neighbors_clv
172 ISIS_CLV_EXTD_IS_REACH,
173 "Extended IS reachability",
174 &ett_isis_lsp_clv_ext_is_reachability,
175 dissect_lsp_ext_is_reachability_clv
178 ISIS_CLV_INT_IP_REACH,
179 "IP Internal reachability",
180 &ett_isis_lsp_clv_ip_reachability,
181 dissect_lsp_ip_reachability_clv
184 ISIS_CLV_EXT_IP_REACH,
185 "IP External reachability",
186 &ett_isis_lsp_clv_ip_reachability,
187 dissect_lsp_ip_reachability_clv
190 ISIS_CLV_EXTD_IP_REACH,
191 "Extended IP Reachability",
192 &ett_isis_lsp_clv_ext_ip_reachability,
193 dissect_lsp_ext_ip_reachability_clv
198 &ett_isis_lsp_clv_ipv6_reachability,
199 dissect_lsp_ipv6_reachability_clv
202 ISIS_CLV_PROTOCOLS_SUPPORTED,
203 "Protocols supported",
204 &ett_isis_lsp_clv_nlpid,
205 dissect_lsp_nlpid_clv
210 &ett_isis_lsp_clv_hostname,
211 dissect_lsp_hostname_clv
214 ISIS_CLV_TE_ROUTER_ID,
215 "Traffic Engineering Router ID",
216 &ett_isis_lsp_clv_te_router_id,
217 dissect_lsp_te_router_id_clv
221 "IP Interface address(es)",
222 &ett_isis_lsp_clv_ipv4_int_addr,
223 dissect_lsp_ip_int_addr_clv
227 "IPv6 Interface address(es)",
228 &ett_isis_lsp_clv_ipv6_int_addr,
229 dissect_lsp_ipv6_int_addr_clv
232 ISIS_CLV_AUTHENTICATION,
234 &ett_isis_lsp_clv_authentication,
235 dissect_lsp_authentication_clv
238 ISIS_CLV_IP_AUTHENTICATION,
240 &ett_isis_lsp_clv_ip_authentication,
241 dissect_lsp_ip_authentication_clv
244 ISIS_CLV_MT_SUPPORTED,
245 "Multi Topology supported",
246 &ett_isis_lsp_clv_mt,
250 ISIS_CLV_MT_IS_REACH,
251 "Multi Topology IS Reachability",
252 &ett_isis_lsp_clv_mt_is,
253 dissect_lsp_mt_is_reachability_clv
256 ISIS_CLV_MT_IP_REACH,
257 "Multi Topology Reachable IPv4 Prefixes",
258 &ett_isis_lsp_clv_mt_reachable_IPv4_prefx,
259 dissect_lsp_mt_reachable_IPv4_prefx_clv
262 ISIS_CLV_MT_IP6_REACH,
263 "Multi Topology Reachable IPv6 Prefixes",
264 &ett_isis_lsp_clv_mt_reachable_IPv6_prefx,
265 dissect_lsp_mt_reachable_IPv6_prefx_clv
275 static const isis_clv_handle_t clv_l2_lsp_opts[] = {
277 ISIS_CLV_AREA_ADDRESS,
279 &ett_isis_lsp_clv_area_addr,
280 dissect_lsp_area_address_clv
285 &ett_isis_lsp_clv_is_neighbors,
286 dissect_lsp_l2_is_neighbors_clv
289 ISIS_CLV_EXTD_IS_REACH,
290 "Extended IS reachability",
291 &ett_isis_lsp_clv_ext_is_reachability,
292 dissect_lsp_ext_is_reachability_clv
295 ISIS_CLV_PARTITION_DIS,
296 "Partition Designated Level 2 IS",
297 &ett_isis_lsp_clv_partition_dis,
298 dissect_lsp_partition_dis_clv
301 ISIS_CLV_PREFIX_NEIGHBORS,
303 &ett_isis_lsp_clv_prefix_neighbors,
304 dissect_lsp_prefix_neighbors_clv
307 ISIS_CLV_INT_IP_REACH,
308 "IP Internal reachability",
309 &ett_isis_lsp_clv_ip_reachability,
310 dissect_lsp_ip_reachability_clv
313 ISIS_CLV_EXT_IP_REACH,
314 "IP External reachability",
315 &ett_isis_lsp_clv_ip_reachability,
316 dissect_lsp_ip_reachability_clv
319 ISIS_CLV_PROTOCOLS_SUPPORTED,
320 "Protocols supported",
321 &ett_isis_lsp_clv_nlpid,
322 dissect_lsp_nlpid_clv
327 &ett_isis_lsp_clv_hostname,
328 dissect_lsp_hostname_clv
331 ISIS_CLV_TE_ROUTER_ID,
332 "Traffic Engineering Router ID",
333 &ett_isis_lsp_clv_te_router_id,
334 dissect_lsp_te_router_id_clv
337 ISIS_CLV_EXTD_IP_REACH,
338 "Extended IP Reachability",
339 &ett_isis_lsp_clv_ext_ip_reachability,
340 dissect_lsp_ext_ip_reachability_clv
345 &ett_isis_lsp_clv_ipv6_reachability,
346 dissect_lsp_ipv6_reachability_clv
350 "IP Interface address(es)",
351 &ett_isis_lsp_clv_ipv4_int_addr,
352 dissect_lsp_ip_int_addr_clv
356 "IPv6 Interface address(es)",
357 &ett_isis_lsp_clv_ipv6_int_addr,
358 dissect_lsp_ipv6_int_addr_clv
361 ISIS_CLV_AUTHENTICATION,
363 &ett_isis_lsp_clv_authentication,
364 dissect_lsp_authentication_clv
367 ISIS_CLV_IP_AUTHENTICATION,
369 &ett_isis_lsp_clv_ip_authentication,
370 dissect_lsp_ip_authentication_clv
373 ISIS_CLV_MT_SUPPORTED,
375 &ett_isis_lsp_clv_mt,
379 ISIS_CLV_MT_IS_REACH,
380 "Multi Topology IS Reachability",
381 &ett_isis_lsp_clv_mt_is,
382 dissect_lsp_mt_is_reachability_clv
385 ISIS_CLV_MT_IP_REACH,
386 "Multi Topology Reachable IPv4 Prefixes",
387 &ett_isis_lsp_clv_mt_reachable_IPv4_prefx,
388 dissect_lsp_mt_reachable_IPv4_prefx_clv
391 ISIS_CLV_MT_IP6_REACH,
392 "Multi Topology Reachable IPv6 Prefixes",
393 &ett_isis_lsp_clv_mt_reachable_IPv6_prefx,
394 dissect_lsp_mt_reachable_IPv6_prefx_clv
405 * Name: dissect_lsp_mt_id()
408 * dissect and display the multi-topology ID value
411 * tvbuff_t * : tvbuffer for packet data
412 * proto_tree * : protocol display tree to fill out. CAN'T BE NULL
413 * int : offset into packet data where we are.
416 * void, but we will add to proto tree.
419 dissect_lsp_mt_id(tvbuff_t *tvb, proto_tree *tree, int offset)
422 const char *mt_desc="";
424 /* fetch two bytes */
425 mt_block = tvb_get_ntohs(tvb, offset);
427 proto_tree_add_text ( tree, tvb, offset, 1 ,
428 "4 most significant bits reserved, should be set to 0 (%d)", ISIS_LSP_MT_MSHIP_RES(mt_block));
430 mt_id = ISIS_LSP_MT_MSHIP_ID(mt_block);
431 /*mask out the lower 12 bits */
434 mt_desc="'standard' topology";
437 mt_desc="IPv4 In-Band Management purposes";
440 mt_desc="IPv6 routing topology";
443 mt_desc="IPv4 multicast routing topology";
446 mt_desc="IPv6 multicast routing topology";
449 mt_desc=((mt_block & 0x0fff) < 3996) ? "Reserved for IETF Consensus" : "Development, Experimental and Proprietary features";
452 proto_tree_add_text ( tree, tvb, offset, 2 ,
453 "%s (%d)", mt_desc, mt_id);
458 * Name: dissect_metric()
461 * Display a metric prefix portion. ISIS has the concept of multple
462 * metric per prefix (default, delay, expense, and error). This
463 * routine assists other dissectors by adding a single one of
464 * these to the display tree..
466 * The 8th(msbit) bit in the metric octet is the "supported" bit. The
467 * "default" support is required, so we support a "force_supported"
468 * flag that tells us that it MUST be zero (zero==supported,
469 * so it really should be a "not supported" in the boolean sense)
470 * and to display a protocol failure accordingly. Notably,
471 * Cisco IOS 12(6) blows this!
472 * The 7th bit must be zero (reserved).
475 * tvbuff_t * : tvbuffer for packet data
476 * proto_tree * : protocol display tree to fill out. May be NULL
477 * int : offset into packet data where we are.
478 * guint8 : value of the metric.
479 * char * : string giving type of the metric.
480 * int : force supported. True is the supported bit MUST be zero.
483 * void, but we will add to proto tree if !NULL.
486 dissect_metric(tvbuff_t *tvb, proto_tree *tree, int offset, guint8 value,
487 const char *pstr, int force_supported )
493 s = ISIS_LSP_CLV_METRIC_SUPPORTED(value);
494 proto_tree_add_text(tree, tvb, offset, 1,
495 "%s Metric: %s%s %s%d:%d", pstr,
496 s ? "Not supported" : "Supported",
497 (s && force_supported) ? "(but is required to be)":"",
498 ISIS_LSP_CLV_METRIC_RESERVED(value) ? "(reserved bit != 0)":"",
499 ISIS_LSP_CLV_METRIC_VALUE(value), value );
503 * Name: dissect_lsp_ip_reachability_clv()
506 * Decode an IP reachability CLV. This can be either internal or
507 * external (the clv format does not change and which type we are
508 * displaying is put there by the dispatcher). All of these
509 * are a metric block followed by an IP addr and mask.
512 * tvbuff_t * : tvbuffer for packet data
513 * proto_tree * : proto tree to build on (may be null)
514 * int : current offset into packet data
515 * int : length of IDs in packet.
516 * int : length of this clv
519 * void, will modify proto_tree if not null.
522 dissect_lsp_ip_reachability_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
523 int id_length _U_, int length)
526 proto_tree *ntree = NULL;
527 guint32 src, mask, bitmask;
529 gboolean found_mask = FALSE;
531 while ( length > 0 ) {
533 isis_dissect_unknown(tvb, tree, offset,
534 "short IP reachability (%d vs 12)", length );
538 * Gotta build a sub-tree for all our pieces
541 src = tvb_get_ipv4(tvb, offset+4);
542 mask = tvb_get_ntohl(tvb, offset+8);
544 /* find out if the mask matches one of 33 possible prefix lengths */
545 bitmask = 0xffffffff;
546 for(prefix_len = 32; prefix_len >= 0; prefix_len--) {
551 bitmask = bitmask << 1;
554 /* If we have a discontiguous netmask, dump the mask, otherwise print the prefix_len */
555 /* XXX - We should probably have some sort of netmask_to_str() routine in to_str.c that does this. */
558 ti = proto_tree_add_text ( tree, tvb, offset, 12,
559 "IPv4 prefix: %s/%d",
560 ip_to_str((guint8*)&src),
563 ti = proto_tree_add_text ( tree, tvb, offset, 12,
564 "IPv4 prefix: %s mask %s",
565 ip_to_str((guint8*)&src),
566 ip_to_str(tvb_get_ptr(tvb, offset+8, 4)));
569 ntree = proto_item_add_subtree(ti,
570 ett_isis_lsp_clv_ip_reachability);
572 proto_tree_add_text (ntree, tvb, offset, 1,
573 "Default Metric: %d, %s, Distribution: %s",
574 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset)),
575 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset)) ? "External" : "Internal",
576 ISIS_LSP_CLV_METRIC_UPDOWN(tvb_get_guint8(tvb, offset)) ? "down" : "up");
579 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+1))) {
580 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: Not supported");
582 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: %d, %s",
583 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+1)),
584 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+1)) ? "External" : "Internal");
587 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+2))) {
588 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: Not supported");
590 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: %d, %s",
591 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+2)),
592 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+2)) ? "External" : "Internal");
595 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+3))) {
596 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: Not supported");
598 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: %d, %s",
599 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+3)),
600 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+3)) ? "External" : "Internal");
609 * Name: dissect_ipreach_subclv ()
611 * Description: parses IP reach subTLVs
612 * Called by various IP Reachability dissectors.
615 * tvbuff_t * : tvbuffer for packet data
616 * proto_tree * : protocol display tree to fill out.
617 * int : offset into packet data where we are (beginning of the sub_clv value).
623 dissect_ipreach_subclv(tvbuff_t *tvb, proto_tree *tree, int offset, int clv_code, int clv_len)
628 while (clv_len >= 4) {
629 proto_tree_add_text(tree, tvb, offset, 4,
630 "32-Bit Administrative tag: 0x%08x (=%u)",
631 tvb_get_ntohl(tvb, offset),
632 tvb_get_ntohl(tvb, offset));
638 while (clv_len >= 8) {
639 proto_tree_add_text(tree, tvb, offset, 8,
640 "64-Bit Administrative tag: 0x%08x%08x",
641 tvb_get_ntohl(tvb, offset),
642 tvb_get_ntohl(tvb, offset+4));
649 proto_tree_add_text (tree, tvb, offset, clv_len+2,
650 "Unknown sub-TLV: code %u, length %u",
658 * Name: dissect_lsp_ext_ip_reachability_clv()
660 * Description: Decode an Extended IP Reachability CLV - code 135.
662 * The extended IP reachability TLV is an extended version
663 * of the IP reachability TLVs (codes 128 and 130). It encodes
664 * the metric as a 32-bit unsigned interger and allows to add
667 * CALLED BY TLV 235 DISSECTOR
671 * tvbuff_t * : tvbuffer for packet data
672 * proto_tree * : proto tree to build on (may be null)
673 * int : current offset into packet data
674 * int : length of IDs in packet.
675 * int : length of this clv
678 * void, will modify proto_tree if not null.
681 dissect_lsp_ext_ip_reachability_clv(tvbuff_t *tvb, proto_tree *tree,
682 int offset, int id_length _U_, int length)
684 proto_item *pi = NULL;
685 proto_tree *subtree = NULL;
686 proto_tree *subtree2 = NULL;
694 guint clv_code, clv_len;
699 ctrl_info = tvb_get_guint8(tvb, offset+4);
700 bit_length = ctrl_info & 0x3f;
701 byte_length = ipv4_addr_and_mask(tvb, offset+5, prefix, bit_length);
702 if (byte_length == -1) {
703 isis_dissect_unknown(tvb, tree, offset,
704 "IPv4 prefix has an invalid length: %d bits", bit_length );
707 metric = tvb_get_ntohl(tvb, offset);
709 if ((ctrl_info & 0x40) != 0)
710 subclvs_len = 1+tvb_get_guint8(tvb, offset+5+byte_length);
712 pi = proto_tree_add_text (tree, tvb, offset, 5+byte_length+subclvs_len,
713 "IPv4 prefix: %s/%d, Metric: %u, Distribution: %s, %ssub-TLVs present",
717 ((ctrl_info & 0x80) == 0) ? "up" : "down",
718 ((ctrl_info & 0x40) == 0) ? "no " : "" );
720 /* open up a new tree per prefix */
721 subtree = proto_item_add_subtree (pi, ett_isis_lsp_part_of_clv_ext_ip_reachability);
723 proto_tree_add_text (subtree, tvb, offset+5, byte_length, "IPv4 prefix: %s/%u",
727 proto_tree_add_text (subtree, tvb, offset, 4, "Metric: %u", metric);
729 proto_tree_add_text (subtree, tvb, offset+4, 1, "Distribution: %s",
730 ((ctrl_info & 0x80) == 0) ? "up" : "down");
732 len = 5 + byte_length;
733 if ((ctrl_info & 0x40) != 0) {
734 subclvs_len = tvb_get_guint8(tvb, offset+len);
735 pi = proto_tree_add_text (subtree, tvb, offset+len, 1, "sub-TLVs present, total length: %u bytes",
737 proto_item_set_len (pi, subclvs_len+1);
738 /* open up a new tree for the subTLVs */
739 subtree2 = proto_item_add_subtree (pi, ett_isis_lsp_clv_ip_reach_subclv);
742 while (i < subclvs_len) {
743 clv_code = tvb_get_guint8(tvb, offset+len+1); /* skip the total subtlv len indicator */
744 clv_len = tvb_get_guint8(tvb, offset+len+2);
747 * we pass on now the raw data to the ipreach_subtlv dissector
748 * therefore we need to skip 3 bytes
749 * (total subtlv len, subtlv type, subtlv len)
751 dissect_ipreach_subclv(tvb, subtree2, offset+len+3, clv_code, clv_len);
754 len += 1 + subclvs_len;
756 proto_tree_add_text (subtree, tvb, offset+4, 1, "no sub-TLVs present");
757 proto_item_set_len (pi, len);
766 * Name: dissect_lsp_ipv6_reachability_clv()
768 * Description: Decode an IPv6 reachability CLV - code 236.
770 * CALLED BY TLV 237 DISSECTOR
773 * tvbuff_t * : tvbuffer for packet data
774 * proto_tree * : proto tree to build on (may be null)
775 * int : current offset into packet data
776 * int : length of IDs in packet.
777 * int : length of this clv
780 * void, will modify proto_tree if not null.
783 dissect_lsp_ipv6_reachability_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
784 int id_length _U_, int length)
787 proto_tree *subtree = NULL;
788 proto_tree *subtree2 = NULL;
792 struct e_in6_addr prefix;
796 guint clv_code, clv_len;
801 ctrl_info = tvb_get_guint8(tvb, offset+4);
802 bit_length = tvb_get_guint8(tvb, offset+5);
803 byte_length = ipv6_addr_and_mask(tvb, offset+6, &prefix, bit_length);
804 if (byte_length == -1) {
805 isis_dissect_unknown(tvb, tree, offset,
806 "IPv6 prefix has an invalid length: %d bits", bit_length );
809 metric = tvb_get_ntohl(tvb, offset);
811 if ((ctrl_info & 0x20) != 0)
812 subclvs_len = 1+tvb_get_guint8(tvb, offset+6+byte_length);
814 pi = proto_tree_add_text (tree, tvb, offset, 6+byte_length+subclvs_len,
815 "IPv6 prefix: %s/%u, Metric: %u, Distribution: %s, %s, %ssub-TLVs present",
816 ip6_to_str (&prefix),
819 ((ctrl_info & 0x80) == 0) ? "up" : "down",
820 ((ctrl_info & 0x40) == 0) ? "internal" : "external",
821 ((ctrl_info & 0x20) == 0) ? "no " : "" );
823 subtree = proto_item_add_subtree (pi, ett_isis_lsp_part_of_clv_ipv6_reachability);
825 proto_tree_add_text (subtree, tvb, offset+6, byte_length, "IPv6 prefix: %s/%u",
826 ip6_to_str (&prefix),
829 proto_tree_add_text (subtree, tvb, offset, 4,
830 "Metric: %u", metric);
832 proto_tree_add_text (subtree, tvb, offset+4, 1,
833 "Distribution: %s, %s",
834 ((ctrl_info & 0x80) == 0) ? "up" : "down",
835 ((ctrl_info & 0x40) == 0) ? "internal" : "external" );
837 if ((ctrl_info & 0x1f) != 0) {
838 proto_tree_add_text (subtree, tvb, offset+4, 1,
839 "Reserved bits: 0x%x",
840 (ctrl_info & 0x1f) );
843 len = 6 + byte_length;
844 if ((ctrl_info & 0x20) != 0) {
845 subclvs_len = tvb_get_guint8(tvb, offset+len);
846 pi = proto_tree_add_text (subtree, tvb, offset+len, 1, "sub-TLVs present, total length: %u bytes",
848 proto_item_set_len (pi, subclvs_len+1);
849 /* open up a new tree for the subTLVs */
850 subtree2 = proto_item_add_subtree (pi, ett_isis_lsp_clv_ip_reach_subclv);
853 while (i < subclvs_len) {
854 clv_code = tvb_get_guint8(tvb, offset+len+1); /* skip the total subtlv len indicator */
855 clv_len = tvb_get_guint8(tvb, offset+len+2);
856 dissect_ipreach_subclv(tvb, subtree2, offset+len+3, clv_code, clv_len);
859 len += 1 + subclvs_len;
861 proto_tree_add_text (subtree, tvb, offset+4, 1, "no sub-TLVs present");
862 proto_item_set_len (pi, len);
870 * Name: dissect_lsp_nlpid_clv()
873 * Decode for a lsp packets NLPID clv. Calls into the
877 * tvbuff_t * : tvbuffer for packet data
878 * proto_tree * : proto tree to build on (may be null)
879 * int : current offset into packet data
880 * int : length of IDs in packet.
881 * int : length of this clv
884 * void, will modify proto_tree if not null.
887 dissect_lsp_nlpid_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
888 int id_length _U_, int length)
890 isis_dissect_nlpid_clv(tvb, tree, offset, length);
894 * Name: dissect_lsp_mt_clv()
896 * Description: - code 229
897 * Decode for a lsp packets Multi Topology clv. Calls into the
901 * tvbuff_t * : tvbuffer for packet data
902 * proto_tree * : proto tree to build on (may be null)
903 * int : current offset into packet data
904 * guint : length of this clv
905 * int : length of IDs in packet.
908 * void, will modify proto_tree if not null.
911 dissect_lsp_mt_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
912 int id_length _U_, int length)
914 isis_dissect_mt_clv(tvb, tree, offset, length, hf_isis_lsp_clv_mt );
918 * Name: dissect_lsp_hostname_clv()
921 * Decode for a lsp packets hostname clv. Calls into the
925 * tvbuff_t * : tvbuffer for packet data
926 * proto_tree * : proto tree to build on (may be null)
927 * int : current offset into packet data
928 * int : length of IDs in packet.
929 * int : length of this clv
932 * void, will modify proto_tree if not null.
935 dissect_lsp_hostname_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
936 int id_length _U_, int length)
938 isis_dissect_hostname_clv(tvb, tree, offset, length,
939 hf_isis_lsp_hostname);
944 * Name: dissect_lsp_te_router_id_clv()
947 * Decode for a lsp packets Traffic Engineering ID clv. Calls into the
951 * tvbuff_t * : tvbuffer for packet data
952 * proto_tree * : proto tree to build on (may be null)
953 * int : current offset into packet data
954 * int : length of IDs in packet.
955 * int : length of this clv
958 * void, will modify proto_tree if not null.
961 dissect_lsp_te_router_id_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
962 int id_length _U_, int length)
964 isis_dissect_te_router_id_clv(tvb, tree, offset, length,
965 hf_isis_lsp_clv_te_router_id );
970 * Name: dissect_lsp_ip_int_addr_clv()
973 * Decode for a lsp packets ip interface addr clv. Calls into the
977 * tvbuff_t * : tvbuffer for packet data
978 * proto_tree * : proto tree to build on (may be null)
979 * int : current offset into packet data
980 * int : length of IDs in packet.
981 * int : length of this clv
984 * void, will modify proto_tree if not null.
987 dissect_lsp_ip_int_addr_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
988 int id_length _U_, int length)
990 isis_dissect_ip_int_clv(tvb, tree, offset, length,
991 hf_isis_lsp_clv_ipv4_int_addr );
995 * Name: dissect_lsp_ipv6_int_addr_clv()
997 * Description: Decode an IPv6 interface addr CLV - code 232.
999 * Calls into the clv common one.
1002 * tvbuff_t * : tvbuffer for packet data
1003 * proto_tree * : proto tree to build on (may be null)
1004 * int : current offset into packet data
1005 * int : length of IDs in packet.
1006 * int : length of this clv
1009 * void, will modify proto_tree if not null.
1012 dissect_lsp_ipv6_int_addr_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1013 int id_length _U_, int length)
1015 isis_dissect_ipv6_int_clv(tvb, tree, offset, length,
1016 hf_isis_lsp_clv_ipv6_int_addr );
1020 * Name: dissect_lsp_authentication_clv()
1023 * Decode for a lsp packets authenticaion clv. Calls into the
1027 * tvbuff_t * : tvbuffer for packet data
1028 * proto_tree * : proto tree to build on (may be null)
1029 * int : current offset into packet data
1030 * int : length of IDs in packet.
1031 * int : length of this clv
1034 * void, will modify proto_tree if not null.
1037 dissect_lsp_authentication_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1038 int id_length _U_, int length)
1040 isis_dissect_authentication_clv(tvb, tree, offset, length);
1044 * Name: dissect_lsp_ip_authentication_clv()
1047 * Decode for a lsp packets authenticaion clv. Calls into the
1051 * tvbuff_t * : tvbuffer for packet data
1052 * proto_tree * : proto tree to build on (may be null)
1053 * int : current offset into packet data
1054 * int : length of IDs in packet.
1055 * int : length of this clv
1058 * void, will modify proto_tree if not null.
1061 dissect_lsp_ip_authentication_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1062 int id_length _U_, int length)
1064 isis_dissect_ip_authentication_clv(tvb, tree, offset, length);
1068 * Name: dissect_lsp_area_address_clv()
1071 * Decode for a lsp packet's area address clv. Call into clv common
1075 * tvbuff_t * : tvbuffer for packet data
1076 * proto_tree * : protocol display tree to fill out. May be NULL
1077 * int : offset into packet data where we are.
1078 * int : length of IDs in packet.
1079 * int : length of clv we are decoding
1082 * void, but we will add to proto tree if !NULL.
1085 dissect_lsp_area_address_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1086 int id_length _U_, int length)
1088 isis_dissect_area_address_clv(tvb, tree, offset, length);
1092 * Name: dissect_lsp_eis_neighbors_clv_inner()
1095 * Real work horse for showing neighbors. This means we decode the
1096 * first octet as either virtual/!virtual (if show_virtual param is
1097 * set), or as a must == 0 reserved value.
1099 * Once past that, we decode n neighbor elements. Each neighbor
1100 * is comprised of a metric block (is dissect_metric) and the
1104 * tvbuff_t * : tvbuffer for packet data
1105 * proto_tree * : protocol display tree to fill out. May be NULL
1106 * int : offset into packet data where we are.
1107 * int : length of IDs in packet.
1108 * int : length of clv we are decoding
1109 * int : set to decode first octet as virtual vs reserved == 0
1110 * int : set to indicate EIS instead of IS (6 octet per addr instead of 7)
1113 * void, but we will add to proto tree if !NULL.
1116 dissect_lsp_eis_neighbors_clv_inner(tvbuff_t *tvb, proto_tree *tree,
1117 int offset, int length, int id_length, int show_virtual, int is_eis)
1120 proto_tree *ntree = NULL;
1124 id_length++; /* IDs are one octet longer in IS neighbours */
1126 if ( show_virtual ) {
1127 /* virtual path flag */
1128 proto_tree_add_text ( tree, tvb, offset, 1,
1129 tvb_get_guint8(tvb, offset) ? "IsVirtual" : "IsNotVirtual" );
1131 proto_tree_add_text ( tree, tvb, offset, 1,
1132 "Reserved value 0x%02x, must == 0",
1133 tvb_get_guint8(tvb, offset) );
1139 tlen = 4 + id_length;
1141 while ( length > 0 ) {
1143 isis_dissect_unknown(tvb, tree, offset,
1144 "short E/IS reachability (%d vs %d)", length,
1149 * Gotta build a sub-tree for all our pieces
1153 ti = proto_tree_add_text(tree, tvb, offset, tlen,
1155 print_system_id( tvb_get_ptr(tvb, offset+4, id_length), id_length ) );
1157 ti = proto_tree_add_text(tree, tvb, offset, tlen,
1159 print_system_id(tvb_get_ptr(tvb, offset+4, id_length), id_length ) );
1161 ntree = proto_item_add_subtree(ti,
1162 ett_isis_lsp_clv_is_neighbors);
1166 proto_tree_add_text (ntree, tvb, offset, 1,
1167 "Default Metric: %d, %s",
1168 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset)),
1169 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset)) ? "External" : "Internal");
1171 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+1))) {
1172 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: Not supported");
1174 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: %d, %s",
1175 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+1)),
1176 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+1)) ? "External" : "Internal");
1180 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+2))) {
1181 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: Not supported");
1183 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: %d, %s",
1184 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+2)),
1185 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+2)) ? "External" : "Internal");
1188 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+3))) {
1189 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: Not supported");
1191 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: %d, %s",
1192 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+3)),
1193 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+3)) ? "External" : "Internal");
1203 * Name: dissect_lsp_l1_is_neighbors_clv()
1206 * Dispatch a l1 intermediate system neighbor by calling
1207 * the inner function with show virtual set to TRUE and is es set to FALSE.
1210 * tvbuff_t * : tvbuffer for packet data
1211 * proto_tree * : protocol display tree to fill out. May be NULL
1212 * int : offset into packet data where we are.
1213 * int : length of IDs in packet.
1214 * int : length of clv we are decoding
1217 * void, but we will add to proto tree if !NULL.
1220 dissect_lsp_l1_is_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1221 int id_length, int length)
1223 dissect_lsp_eis_neighbors_clv_inner(tvb, tree, offset,
1224 length, id_length, TRUE, FALSE);
1228 * Name: dissect_lsp_l1_es_neighbors_clv()
1231 * Dispatch a l1 end or intermediate system neighbor by calling
1232 * the inner function with show virtual set to TRUE and es set to TRUE.
1235 * tvbuff_t * : tvbuffer for packet data
1236 * proto_tree * : protocol display tree to fill out. May be NULL
1237 * int : offset into packet data where we are.
1238 * int : length of IDs in packet.
1239 * int : length of clv we are decoding
1242 * void, but we will add to proto tree if !NULL.
1245 dissect_lsp_l1_es_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1246 int id_length, int length)
1248 dissect_lsp_eis_neighbors_clv_inner(tvb, tree, offset,
1249 length, id_length, TRUE, TRUE);
1253 * Name: dissect_lsp_l2_is_neighbors_clv()
1256 * Dispatch a l2 intermediate system neighbor by calling
1257 * the inner function with show virtual set to FALSE, and is es set
1261 * tvbuff_t * : tvbuffer for packet data
1262 * proto_tree * : protocol display tree to fill out. May be NULL
1263 * int : offset into packet data where we are.
1264 * int : length of IDs in packet.
1265 * int : length of clv we are decoding
1268 * void, but we will add to proto tree if !NULL.
1271 dissect_lsp_l2_is_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1272 int id_length, int length)
1274 dissect_lsp_eis_neighbors_clv_inner(tvb, tree, offset,
1275 length, id_length, FALSE, FALSE);
1280 * Name: dissect_subclv_admin_group ()
1282 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1284 * This function is called by dissect_lsp_ext_is_reachability_clv()
1285 * for dissect the administrive group sub-CLV (code 3).
1288 * tvbuff_t * : tvbuffer for packet data
1289 * proto_tree * : protocol display tree to fill out.
1290 * int : offset into packet data where we are (beginning of the sub_clv value).
1296 dissect_subclv_admin_group (tvbuff_t *tvb, proto_tree *tree, int offset) {
1303 ti = proto_tree_add_text(tree, tvb, offset-2, 6, "Administrative group(s):");
1304 ntree = proto_item_add_subtree (ti, ett_isis_lsp_subclv_admin_group);
1306 clv_value = tvb_get_ntohl(tvb, offset);
1308 for (i = 0 ; i < 32 ; i++) {
1309 if ( (clv_value & mask) != 0 ) {
1310 proto_tree_add_text (ntree, tvb, offset, 4, "group %d", i);
1317 * Name: dissect_subclv_max_bw ()
1319 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1321 * This function is called by dissect_lsp_ext_is_reachability_clv()
1322 * for dissect the maximum link bandwidth sub-CLV (code 9).
1325 * tvbuff_t * : tvbuffer for packet data
1326 * proto_tree * : protocol display tree to fill out.
1327 * int : offset into packet data where we are (beginning of the sub_clv value).
1333 dissect_subclv_max_bw(tvbuff_t *tvb, proto_tree *tree, int offset)
1337 bw = tvb_get_ntohieee_float(tvb, offset);
1338 proto_tree_add_text (tree, tvb, offset-2, 6,
1339 "Maximum link bandwidth : %.2f Mbps", bw*8/1000000 );
1343 * Name: dissect_subclv_rsv_bw ()
1345 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1347 * This function is called by dissect_lsp_ext_is_reachability_clv()
1348 * for dissect the reservable link bandwidth sub-CLV (code 10).
1351 * tvbuff_t * : tvbuffer for packet data
1352 * proto_tree * : protocol display tree to fill out.
1353 * int : offset into packet data where we are (beginning of the sub_clv value).
1359 dissect_subclv_rsv_bw(tvbuff_t *tvb, proto_tree *tree, int offset)
1363 bw = tvb_get_ntohieee_float(tvb, offset);
1364 proto_tree_add_text (tree, tvb, offset-2, 6,
1365 "Reservable link bandwidth: %.2f Mbps", bw*8/1000000 );
1369 * Name: dissect_subclv_unrsv_bw ()
1371 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1373 * This function is called by dissect_lsp_ext_is_reachability_clv()
1374 * for dissect the unreserved bandwidth sub-CLV (code 11).
1377 * tvbuff_t * : tvbuffer for packet data
1378 * proto_tree * : protocol display tree to fill out.
1379 * int : offset into packet data where we are (beginning of the sub_clv value).
1385 dissect_subclv_unrsv_bw(tvbuff_t *tvb, proto_tree *tree, int offset)
1392 ti = proto_tree_add_text (tree, tvb, offset-2, 34, "Unreserved bandwidth:");
1393 ntree = proto_item_add_subtree (ti, ett_isis_lsp_subclv_unrsv_bw);
1395 for (i = 0 ; i < 8 ; i++) {
1396 bw = tvb_get_ntohieee_float(tvb, offset+4*i);
1397 proto_tree_add_text (ntree, tvb, offset+4*i, 4,
1398 "priority level %d: %.2f Mbps", i, bw*8/1000000 );
1403 * Name: dissect_lsp_ext_is_reachability_clv()
1405 * Description: Decode a Extended IS Reachability CLV - code 22
1407 * The extended IS reachability TLV is an extended version
1408 * of the IS reachability TLV (code 2). It encodes the metric
1409 * as a 24-bit unsigned interger and allows to add sub-CLV(s).
1411 * CALLED BY TLV 222 DISSECTOR
1414 * tvbuff_t * : tvbuffer for packet data
1415 * proto_tree * : protocol display tree to fill out. May be NULL
1416 * int : offset into packet data where we are.
1417 * int : length of IDs in packet.
1418 * int : length of clv we are decoding
1421 * void, but we will add to proto tree if !NULL.
1424 dissect_lsp_ext_is_reachability_clv(tvbuff_t *tvb, proto_tree *tree,
1425 int offset, int id_length _U_, int length)
1428 proto_tree *ntree = NULL;
1431 guint clv_code, clv_len;
1435 while (length > 0) {
1436 ti = proto_tree_add_text (tree, tvb, offset, -1,
1438 print_system_id (tvb_get_ptr(tvb, offset, 7), 7) );
1439 ntree = proto_item_add_subtree (ti,
1440 ett_isis_lsp_part_of_clv_ext_is_reachability );
1442 proto_tree_add_text (ntree, tvb, offset+7, 3,
1443 "Metric: %d", tvb_get_ntoh24(tvb, offset+7) );
1445 subclvs_len = tvb_get_guint8(tvb, offset+10);
1446 if (subclvs_len == 0) {
1447 proto_tree_add_text (ntree, tvb, offset+10, 1, "no sub-TLVs present");
1451 while (i < subclvs_len) {
1452 clv_code = tvb_get_guint8(tvb, offset+11+i);
1453 clv_len = tvb_get_guint8(tvb, offset+12+i);
1456 dissect_subclv_admin_group(tvb, ntree, offset+13+i);
1459 proto_tree_add_text (ntree, tvb, offset+11+i, 6,
1460 "IPv4 interface address: %s", ip_to_str (tvb_get_ptr(tvb, offset+13+i, 4)) );
1463 proto_tree_add_text (ntree, tvb, offset+11+i, 6,
1464 "IPv4 neighbor address: %s", ip_to_str (tvb_get_ptr(tvb, offset+13+i, 4)) );
1467 dissect_subclv_max_bw (tvb, ntree, offset+13+i);
1470 dissect_subclv_rsv_bw (tvb, ntree, offset+13+i);
1473 dissect_subclv_unrsv_bw (tvb, ntree, offset+13+i);
1476 proto_tree_add_text (ntree, tvb, offset+11+i, 5,
1477 "Traffic engineering default metric: %d",
1478 tvb_get_ntoh24(tvb, offset+13+i) );
1485 proto_tree_add_text (ntree, tvb, offset+11+i, clv_len+2,
1486 "Unknown Cisco specific extensions: code %d, length %d",
1487 clv_code, clv_len );
1490 proto_tree_add_text (ntree, tvb, offset+11+i, clv_len+2,
1491 "Unknown sub-CLV: code %d, length %d", clv_code, clv_len );
1498 len = 11 + subclvs_len;
1499 proto_item_set_len (ti, len);
1506 * Name: dissect_lsp_mt_reachable_IPv4_prefx_clv()
1508 * Description: Decode Multi-Topology IPv4 Prefixes - code 235
1512 * tvbuff_t * : tvbuffer for packet data
1513 * proto_tree * : protocol display tree to fill out. May be NULL
1514 * int : offset into packet data where we are.
1515 * int : length of IDs in packet.
1516 * int : length of clv we are decoding
1519 * void, but we will add to proto tree if !NULL.
1522 dissect_lsp_mt_reachable_IPv4_prefx_clv(tvbuff_t *tvb,
1523 proto_tree *tree, int offset, int id_length _U_, int length)
1527 isis_dissect_unknown(tvb, tree, offset,
1528 "short lsp multi-topology reachable IPv4 prefixes(%d vs %d)", length,
1532 dissect_lsp_mt_id(tvb, tree, offset);
1533 dissect_lsp_ext_ip_reachability_clv(tvb, tree, offset+2, 0, length-2);
1537 * Name: dissect_lsp_mt_reachable_IPv6_prefx_clv()
1539 * Description: Decode Multi-Topology IPv6 Prefixes - code 237
1543 * tvbuff_t * : tvbuffer for packet data
1544 * proto_tree * : protocol display tree to fill out. May be NULL
1545 * int : offset into packet data where we are.
1546 * int : length of IDs in packet.
1547 * int : length of clv we are decoding
1550 * void, but we will add to proto tree if !NULL.
1553 dissect_lsp_mt_reachable_IPv6_prefx_clv(tvbuff_t *tvb,
1554 proto_tree *tree, int offset, int id_length _U_, int length)
1558 isis_dissect_unknown(tvb, tree, offset,
1559 "short lsp multi-topology reachable IPv6 prefixes(%d vs %d)", length,
1563 dissect_lsp_mt_id(tvb, tree, offset);
1564 dissect_lsp_ipv6_reachability_clv(tvb, tree, offset+2, 0, length-2);
1569 * Name: dissect_lsp_mt_is_reachability_clv()
1571 * Description: Decode Multi-Topology Intermediate Systems - code 222
1575 * tvbuff_t * : tvbuffer for packet data
1576 * proto_tree * : protocol display tree to fill out. May be NULL
1577 * int : offset into packet data where we are.
1579 * int : length of clv we are decoding
1582 * void, but we will add to proto tree if !NULL.
1586 dissect_lsp_mt_is_reachability_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1587 int id_length _U_, int length)
1591 isis_dissect_unknown(tvb, tree, offset,
1592 "short lsp reachability(%d vs %d)", length,
1598 * the MT ID value dissection is used in other LSPs so we push it
1601 dissect_lsp_mt_id(tvb, tree, offset);
1603 * fix here. No need to parse TLV 22 (with bugs) while it is
1604 * already done correctly!!
1606 dissect_lsp_ext_is_reachability_clv(tvb, tree, offset+2, 0, length-2);
1610 * Name: dissect_lsp_partition_dis_clv()
1613 * This CLV is used to indicate which system is the designated
1614 * IS for partition repair. This means just putting out the
1615 * "id_length"-octet IS.
1618 * tvbuff_t * : tvbuffer for packet data
1619 * proto_tree * : protocol display tree to fill out. May be NULL
1620 * int : offset into packet data where we are.
1621 * int : length of IDs in packet.
1622 * int : length of clv we are decoding
1625 * void, but we will add to proto tree if !NULL.
1628 dissect_lsp_partition_dis_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1629 int id_length, int length)
1631 if ( length < id_length ) {
1632 isis_dissect_unknown(tvb, tree, offset,
1633 "short lsp partition DIS(%d vs %d)", length,
1638 * Gotta build a sub-tree for all our pieces
1641 proto_tree_add_text ( tree, tvb, offset, id_length,
1642 "Partition designated L2 IS: %s",
1643 print_system_id( tvb_get_ptr(tvb, offset, id_length), id_length ) );
1645 length -= id_length;
1646 offset += id_length;
1648 isis_dissect_unknown(tvb, tree, offset,
1649 "Long lsp partition DIS, %d left over", length );
1655 * Name: dissect_lsp_prefix_neighbors_clv()
1658 * The prefix CLV describes what other (OSI) networks we can reach
1659 * and what their cost is. It is built from a metric block
1660 * (see dissect_metric) followed by n addresses.
1663 * tvbuff_t * : tvbuffer for packet data
1664 * proto_tree * : protocol display tree to fill out. May be NULL
1665 * int : offset into packet data where we are.
1666 * int : length of IDs in packet.
1667 * int : length of clv we are decoding
1670 * void, but we will add to proto tree if !NULL.
1673 dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1674 int id_length _U_, int length)
1680 isis_dissect_unknown(tvb, tree, offset,
1681 "Short lsp prefix neighbors (%d vs 4)", length );
1685 dissect_metric (tvb, tree, offset,
1686 tvb_get_guint8(tvb, offset), "Default", TRUE );
1687 dissect_metric (tvb, tree, offset+1,
1688 tvb_get_guint8(tvb, offset+1), "Delay", FALSE );
1689 dissect_metric (tvb, tree, offset+2,
1690 tvb_get_guint8(tvb, offset+2), "Expense", FALSE );
1691 dissect_metric (tvb, tree, offset+3,
1692 tvb_get_guint8(tvb, offset+3), "Error", FALSE );
1696 while ( length > 0 ) {
1697 mylen = tvb_get_guint8(tvb, offset);
1700 isis_dissect_unknown(tvb, tree, offset,
1701 "Zero payload space after length in prefix neighbor" );
1704 if ( mylen > length) {
1705 isis_dissect_unknown(tvb, tree, offset,
1706 "Integral length of prefix neighbor too long (%d vs %d)",
1712 * Lets turn the area address into "standard" 0000.0000.etc
1715 sbuf = print_area( tvb_get_ptr(tvb, offset+1, mylen), mylen );
1716 /* and spit it out */
1718 proto_tree_add_text ( tree, tvb, offset, mylen + 1,
1719 "Area address (%d): %s", mylen, sbuf );
1721 offset += mylen + 1;
1722 length -= mylen; /* length already adjusted for len fld*/
1726 static void isis_lsp_checkum_additional_info(tvbuff_t * tvb, packet_info * pinfo,
1727 proto_item * it_cksum, int offset, gboolean is_cksum_correct)
1729 proto_tree * checksum_tree;
1732 checksum_tree = proto_item_add_subtree(it_cksum, ett_isis_lsp_cksum);
1733 item = proto_tree_add_boolean(checksum_tree, hf_isis_lsp_checksum_good, tvb,
1734 offset, 2, is_cksum_correct);
1735 PROTO_ITEM_SET_GENERATED(item);
1736 item = proto_tree_add_boolean(checksum_tree, hf_isis_lsp_checksum_bad, tvb,
1737 offset, 2, !is_cksum_correct);
1738 PROTO_ITEM_SET_GENERATED(item);
1739 if (!is_cksum_correct) {
1740 expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_ERROR, "Bad checksum");
1741 col_append_str(pinfo->cinfo, COL_INFO, " [ISIS CHECKSUM INCORRECT]");
1747 * Name: isis_dissect_isis_lsp()
1750 * Print out the LSP part of the main header and then call the CLV
1751 * de-mangler with the right list of valid CLVs.
1754 * tvbuff_t * : tvbuffer for packet data
1755 * proto_tree * : protocol display tree to add to. May be NULL.
1756 * int offset : our offset into packet data.
1757 * int : LSP type, a la packet-isis.h ISIS_TYPE_* values
1758 * int : header length of packet.
1759 * int : length of IDs in packet.
1762 * void, but we will add to proto tree if !NULL.
1765 isis_dissect_isis_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
1766 int lsp_type, int header_length, int id_length)
1768 proto_item *ti, *to, *ta;
1769 proto_tree *lsp_tree = NULL, *info_tree, *att_tree;
1770 guint16 pdu_length, lifetime, checksum, cacl_checksum=0;
1771 guint8 lsp_info, lsp_att;
1772 int len, offset_checksum;
1773 proto_item *it_cksum;
1776 ti = proto_tree_add_text(tree, tvb, offset, -1,
1778 lsp_tree = proto_item_add_subtree(ti, ett_isis_lsp);
1781 pdu_length = tvb_get_ntohs(tvb, offset);
1783 proto_tree_add_uint(lsp_tree, hf_isis_lsp_pdu_length, tvb,
1784 offset, 2, pdu_length);
1789 proto_tree_add_item(lsp_tree, hf_isis_lsp_remaining_life,
1790 tvb, offset, 2, FALSE);
1792 lifetime = tvb_get_ntohs(tvb, offset);
1794 offset_checksum = offset;
1797 char* value = print_system_id( tvb_get_ptr(tvb, offset, id_length+2),
1799 proto_tree_add_string_format(lsp_tree, hf_isis_lsp_lsp_id,
1800 tvb, offset, id_length + 2,
1801 value, "LSP-ID: %s", value);
1804 if (check_col(pinfo->cinfo, COL_INFO)) {
1805 col_append_fstr(pinfo->cinfo, COL_INFO, ", LSP-ID: %s",
1806 print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) );
1808 offset += id_length + 2;
1811 proto_tree_add_item(lsp_tree, hf_isis_lsp_sequence_number,
1812 tvb, offset, 4, FALSE);
1814 if (check_col(pinfo->cinfo, COL_INFO)) {
1815 col_append_fstr(pinfo->cinfo, COL_INFO, ", Sequence: 0x%08x, Lifetime: %5us",
1816 tvb_get_ntohl(tvb, offset),
1817 tvb_get_ntohs(tvb, offset - (id_length+2+2)));
1822 checksum = lifetime ? tvb_get_ntohs(tvb, offset) : 0;
1823 switch (check_and_get_checksum(tvb, offset_checksum, pdu_length-12, checksum, offset, &cacl_checksum))
1826 checksum = tvb_get_ntohs(tvb, offset);
1827 proto_tree_add_uint_format(lsp_tree, hf_isis_lsp_checksum, tvb, offset, 2, checksum,
1828 "Checksum: 0x%04x [unused]", checksum);
1831 isis_dissect_unknown(tvb, tree, offset,
1832 "[packet length %d went beyond packet]",
1833 tvb_length_remaining(tvb, offset_checksum));
1836 it_cksum = proto_tree_add_uint_format(lsp_tree, hf_isis_lsp_checksum, tvb, offset, 2, checksum,
1837 "Checksum: 0x%04x [incorrect, should be 0x%04x]",
1838 checksum, cacl_checksum);
1839 isis_lsp_checkum_additional_info(tvb, pinfo, it_cksum, offset, FALSE);
1842 it_cksum = proto_tree_add_uint_format(lsp_tree, hf_isis_lsp_checksum, tvb, offset, 2, checksum,
1843 "Checksum: 0x%04x [correct]", checksum);
1844 isis_lsp_checkum_additional_info(tvb, pinfo, it_cksum, offset, TRUE);
1847 g_message("'check_and_get_checksum' returned an invalid value");
1854 * P | ATT | HIPPITY | IS TYPE description.
1856 lsp_info = tvb_get_guint8(tvb, offset);
1857 to = proto_tree_add_text(lsp_tree, tvb, offset, 1,
1858 "Type block(0x%02x): Partition Repair:%d, Attached bits:%d, Overload bit:%d, IS type:%d",
1860 ISIS_LSP_PARTITION(lsp_info),
1861 ISIS_LSP_ATT(lsp_info),
1862 ISIS_LSP_HIPPITY(lsp_info),
1863 ISIS_LSP_IS_TYPE(lsp_info)
1866 info_tree = proto_item_add_subtree(to, ett_isis_lsp_info);
1867 proto_tree_add_boolean(info_tree, hf_isis_lsp_p, tvb, offset, 1, lsp_info);
1868 ta = proto_tree_add_uint(info_tree, hf_isis_lsp_att, tvb, offset, 1, lsp_info);
1869 att_tree = proto_item_add_subtree(ta, ett_isis_lsp_att);
1870 lsp_att = ISIS_LSP_ATT(lsp_info);
1871 proto_tree_add_text(att_tree, tvb, offset, 1,
1872 "%d... = Error metric: %s", ISIS_LSP_ATT_ERROR(lsp_att), ISIS_LSP_ATT_ERROR(lsp_att) ? "Set" : "Unset");
1873 proto_tree_add_text(att_tree, tvb, offset, 1,
1874 ".%d.. = Expense metric: %s", ISIS_LSP_ATT_EXPENSE(lsp_att), ISIS_LSP_ATT_EXPENSE(lsp_att) ? "Set" : "Unset");
1875 proto_tree_add_text(att_tree, tvb, offset, 1,
1876 "..%d. = Delay metric: %s", ISIS_LSP_ATT_DELAY(lsp_att), ISIS_LSP_ATT_DELAY(lsp_att) ? "Set" : "Unset");
1877 proto_tree_add_text(att_tree, tvb, offset, 1,
1878 "...%d = Default metric: %s", ISIS_LSP_ATT_DEFAULT(lsp_att), ISIS_LSP_ATT_DEFAULT(lsp_att) ? "Set" : "Unset");
1879 proto_tree_add_boolean(info_tree, hf_isis_lsp_hippity, tvb, offset, 1, lsp_info);
1880 proto_tree_add_uint(info_tree, hf_isis_lsp_is_type, tvb, offset, 1, lsp_info);
1884 len = pdu_length - header_length;
1886 isis_dissect_unknown(tvb, tree, offset,
1887 "packet header length %d went beyond packet",
1892 * Now, we need to decode our CLVs. We need to pass in
1893 * our list of valid ones!
1895 if (lsp_type == ISIS_TYPE_L1_LSP){
1896 isis_dissect_clvs(tvb, lsp_tree, offset,
1897 clv_l1_lsp_opts, len, id_length,
1898 ett_isis_lsp_clv_unknown );
1900 isis_dissect_clvs(tvb, lsp_tree, offset,
1901 clv_l2_lsp_opts, len, id_length,
1902 ett_isis_lsp_clv_unknown );
1906 * Name: isis_register_lsp()
1909 * Register our protocol sub-sets with protocol manager.
1912 * int : protocol index for the ISIS protocol
1918 isis_register_lsp(int proto_isis) {
1919 static hf_register_info hf[] = {
1920 { &hf_isis_lsp_pdu_length,
1921 { "PDU length", "isis.lsp.pdu_length", FT_UINT16,
1922 BASE_DEC, NULL, 0x0, NULL, HFILL }},
1924 { &hf_isis_lsp_remaining_life,
1925 { "Remaining lifetime", "isis.lsp.remaining_life", FT_UINT16,
1926 BASE_DEC, NULL, 0x0, NULL, HFILL }},
1928 { &hf_isis_lsp_lsp_id,
1929 { "LSP-ID", "isis.lsp.lsp_id", FT_STRING,
1930 BASE_NONE, NULL, 0x0, NULL, HFILL }},
1932 { &hf_isis_lsp_hostname,
1933 { "Hostname", "isis.lsp.hostname", FT_STRING,
1934 BASE_NONE, NULL, 0x0, NULL, HFILL }},
1936 { &hf_isis_lsp_sequence_number,
1937 { "Sequence number", "isis.lsp.sequence_number",
1938 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1940 { &hf_isis_lsp_checksum,
1941 { "Checksum", "isis.lsp.checksum",FT_UINT16,
1942 BASE_HEX, NULL, 0x0, NULL, HFILL }},
1944 { &hf_isis_lsp_checksum_good,
1945 { "Good Checksum", "isis.lsp.checksum_good", FT_BOOLEAN, BASE_NONE,
1946 NULL, 0x0, "Good IS-IS LSP Checksum", HFILL }},
1948 { &hf_isis_lsp_checksum_bad,
1949 { "Bad Checksum", "isis.lsp.checksum_bad", FT_BOOLEAN, BASE_NONE,
1950 NULL, 0x0, "Bad IS-IS LSP Checksum", HFILL }},
1952 { &hf_isis_lsp_clv_ipv4_int_addr,
1953 { "IPv4 interface address", "isis.lsp.clv_ipv4_int_addr", FT_IPv4,
1954 BASE_NONE, NULL, 0x0, NULL, HFILL }},
1956 { &hf_isis_lsp_clv_ipv6_int_addr,
1957 { "IPv6 interface address", "isis.lsp.clv_ipv6_int_addr", FT_IPv6,
1958 BASE_NONE, NULL, 0x0, NULL, HFILL }},
1960 { &hf_isis_lsp_clv_te_router_id,
1961 { "Traffic Engineering Router ID", "isis.lsp.clv_te_router_id", FT_IPv4,
1962 BASE_NONE, NULL, 0x0, NULL, HFILL }},
1964 { &hf_isis_lsp_clv_mt,
1965 { "MT-ID", "isis.lsp.clv_mt",
1966 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1969 { "Partition Repair", "isis.lsp.partition_repair", FT_BOOLEAN, 8,
1970 TFS(&tfs_supported_not_supported), ISIS_LSP_PARTITION_MASK,
1971 "If set, this router supports the optional Partition Repair function", HFILL }},
1974 { "Attachment", "isis.lsp.att", FT_UINT8, BASE_DEC,
1975 NULL, ISIS_LSP_ATT_MASK,
1978 { &hf_isis_lsp_hippity,
1979 { "Overload bit", "isis.lsp.overload", FT_BOOLEAN, 8,
1980 TFS(&tfs_set_notset), ISIS_LSP_HIPPITY_MASK,
1981 "If set, this router will not be used by any decision process to calculate routes", HFILL }},
1983 { &hf_isis_lsp_is_type,
1984 { "Type of Intermediate System", "isis.lsp.is_type", FT_UINT8, BASE_DEC,
1985 VALS(isis_lsp_istype_vals), ISIS_LSP_IS_TYPE_MASK,
1988 static gint *ett[] = {
1992 &ett_isis_lsp_cksum,
1993 &ett_isis_lsp_clv_area_addr,
1994 &ett_isis_lsp_clv_is_neighbors,
1995 &ett_isis_lsp_clv_ext_is_reachability, /* CLV 22 */
1996 &ett_isis_lsp_part_of_clv_ext_is_reachability,
1997 &ett_isis_lsp_subclv_admin_group,
1998 &ett_isis_lsp_subclv_unrsv_bw,
1999 &ett_isis_lsp_clv_unknown,
2000 &ett_isis_lsp_clv_partition_dis,
2001 &ett_isis_lsp_clv_prefix_neighbors,
2002 &ett_isis_lsp_clv_authentication,
2003 &ett_isis_lsp_clv_ip_authentication,
2004 &ett_isis_lsp_clv_nlpid,
2005 &ett_isis_lsp_clv_hostname,
2006 &ett_isis_lsp_clv_ipv4_int_addr,
2007 &ett_isis_lsp_clv_ipv6_int_addr, /* CLV 232 */
2008 &ett_isis_lsp_clv_te_router_id,
2009 &ett_isis_lsp_clv_ip_reachability,
2010 &ett_isis_lsp_clv_ip_reach_subclv,
2011 &ett_isis_lsp_clv_ext_ip_reachability, /* CLV 135 */
2012 &ett_isis_lsp_part_of_clv_ext_ip_reachability,
2013 &ett_isis_lsp_clv_ipv6_reachability, /* CLV 236 */
2014 &ett_isis_lsp_part_of_clv_ipv6_reachability,
2015 &ett_isis_lsp_clv_mt,
2016 &ett_isis_lsp_clv_mt_is,
2017 &ett_isis_lsp_part_of_clv_mt_is,
2018 &ett_isis_lsp_clv_mt_reachable_IPv4_prefx,
2019 &ett_isis_lsp_clv_mt_reachable_IPv6_prefx
2022 proto_register_field_array(proto_isis, hf, array_length(hf));
2023 proto_register_subtree_array(ett, array_length(ett));