2 * Routines for decoding isis lsp packets and their CLVs
4 * $Id: packet-isis-lsp.c,v 1.46 2003/12/08 20:40:33 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.
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/resolv.h>
44 static int hf_isis_lsp_pdu_length = -1;
45 static int hf_isis_lsp_remaining_life = -1;
46 static int hf_isis_lsp_sequence_number = -1;
47 static int hf_isis_lsp_checksum = -1;
48 static int hf_isis_lsp_checksum_bad = -1;
49 static int hf_isis_lsp_clv_ipv4_int_addr = -1;
50 static int hf_isis_lsp_clv_ipv6_int_addr = -1;
51 static int hf_isis_lsp_clv_te_router_id = -1;
52 static int hf_isis_lsp_clv_mt = -1;
53 static int hf_isis_lsp_p = -1;
54 static int hf_isis_lsp_att = -1;
55 static int hf_isis_lsp_hippity = -1;
56 static int hf_isis_lsp_is_type = -1;
58 static gint ett_isis_lsp = -1;
59 static gint ett_isis_lsp_info = -1;
60 static gint ett_isis_lsp_att = -1;
61 static gint ett_isis_lsp_clv_area_addr = -1;
62 static gint ett_isis_lsp_clv_is_neighbors = -1;
63 static gint ett_isis_lsp_clv_ext_is_reachability = -1; /* CLV 22 */
64 static gint ett_isis_lsp_part_of_clv_ext_is_reachability = -1;
65 static gint ett_isis_lsp_subclv_admin_group = -1;
66 static gint ett_isis_lsp_subclv_unrsv_bw = -1;
67 static gint ett_isis_lsp_clv_unknown = -1;
68 static gint ett_isis_lsp_clv_partition_dis = -1;
69 static gint ett_isis_lsp_clv_prefix_neighbors = -1;
70 static gint ett_isis_lsp_clv_nlpid = -1;
71 static gint ett_isis_lsp_clv_hostname = -1;
72 static gint ett_isis_lsp_clv_te_router_id = -1;
73 static gint ett_isis_lsp_clv_authentication = -1;
74 static gint ett_isis_lsp_clv_ip_authentication = -1;
75 static gint ett_isis_lsp_clv_ipv4_int_addr = -1;
76 static gint ett_isis_lsp_clv_ipv6_int_addr = -1; /* CLV 232 */
77 static gint ett_isis_lsp_clv_ip_reachability = -1;
78 static gint ett_isis_lsp_clv_ip_reach_subclv = -1;
79 static gint ett_isis_lsp_clv_ext_ip_reachability = -1; /* CLV 135 */
80 static gint ett_isis_lsp_part_of_clv_ext_ip_reachability = -1;
81 static gint ett_isis_lsp_clv_ipv6_reachability = -1; /* CLV 236 */
82 static gint ett_isis_lsp_part_of_clv_ipv6_reachability = -1;
83 static gint ett_isis_lsp_clv_mt = -1;
84 static gint ett_isis_lsp_clv_mt_is = -1;
85 static gint ett_isis_lsp_part_of_clv_mt_is = -1;
86 static gint ett_isis_lsp_clv_mt_reachable_IPv4_prefx = -1; /* CLV 235 */
87 static gint ett_isis_lsp_clv_mt_reachable_IPv6_prefx = -1; /* CLV 237 */
89 static const value_string isis_lsp_istype_vals[] = {
90 { ISIS_LSP_TYPE_UNUSED0, "Unused 0x0 (invalid)"},
91 { ISIS_LSP_TYPE_LEVEL_1, "Level 1"},
92 { ISIS_LSP_TYPE_UNUSED2, "Unused 0x2 (invalid)"},
93 { ISIS_LSP_TYPE_LEVEL_2, "Level 2"},
96 static const true_false_string supported_string = {
101 static const true_false_string hippity_string = {
108 * Predclare dissectors for use in clv dissection.
110 static void dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb,
111 proto_tree *tree, int offset, int id_length, int length);
112 static void dissect_lsp_partition_dis_clv(tvbuff_t *tvb,
113 proto_tree *tree, int offset, int id_length, int length);
114 static void dissect_lsp_mt_is_reachability_clv(tvbuff_t *tvb,
115 proto_tree *tree, int offset, int id_length, int length);
116 static void dissect_lsp_ext_is_reachability_clv(tvbuff_t *tvb,
117 proto_tree *tree, int offset, int id_length, int length);
118 static void dissect_lsp_l2_is_neighbors_clv(tvbuff_t *tvb,
119 proto_tree *tree, int offset, int id_length, int length);
120 static void dissect_lsp_l1_es_neighbors_clv(tvbuff_t *tvb,
121 proto_tree *tree, int offset, int id_length, int length);
122 static void dissect_lsp_l1_is_neighbors_clv(tvbuff_t *tvb,
123 proto_tree *tree, int offset, int id_length, int length);
124 static void dissect_lsp_area_address_clv(tvbuff_t *tvb,
125 proto_tree *tree, int offset, int id_length, int length);
126 static void dissect_lsp_authentication_clv(tvbuff_t *tvb,
127 proto_tree *tree, int offset, int id_length, int length);
128 static void dissect_lsp_ip_authentication_clv(tvbuff_t *tvb,
129 proto_tree *tree, int offset, int id_length, int length);
130 static void dissect_lsp_ipv6_int_addr_clv(tvbuff_t *tvb,
131 proto_tree *tree, int offset, int id_length, int length);
132 static void dissect_lsp_ip_int_addr_clv(tvbuff_t *tvb,
133 proto_tree *tree, int offset, int id_length, int length);
134 static void dissect_lsp_te_router_id_clv(tvbuff_t *tvb,
135 proto_tree *tree, int offset, int id_length, int length);
136 static void dissect_lsp_hostname_clv(tvbuff_t *tvb,
137 proto_tree *tree, int offset, int id_length, int length);
138 static void dissect_lsp_mt_clv(tvbuff_t *tvb,
139 proto_tree *tree, int offset, int id_length, int length);
140 static void dissect_lsp_nlpid_clv(tvbuff_t *tvb,
141 proto_tree *tree, int offset, int id_length, int length);
142 static void dissect_lsp_ipv6_reachability_clv(tvbuff_t *tvb,
143 proto_tree *tree, int offset, int id_length, int length);
144 static void dissect_lsp_ext_ip_reachability_clv(tvbuff_t *tvb,
145 proto_tree *tree, int offset, int id_length, int length);
146 static void dissect_lsp_ip_reachability_clv(tvbuff_t *tvb,
147 proto_tree *tree, int offset, int id_length, int length);
148 static void dissect_ipreach_subclv(tvbuff_t *tvb,
149 proto_tree *tree, int offset, int clv_code, int clv_len);
150 static void dissect_lsp_mt_reachable_IPv4_prefx_clv(tvbuff_t *tvb,
151 proto_tree *tree, int offset, int id_length, int length);
152 static void dissect_lsp_mt_reachable_IPv6_prefx_clv(tvbuff_t *tvb,
153 proto_tree *tree, int offset, int id_length, int length);
156 static const isis_clv_handle_t clv_l1_lsp_opts[] = {
158 ISIS_CLV_AREA_ADDRESS,
160 &ett_isis_lsp_clv_area_addr,
161 dissect_lsp_area_address_clv
166 &ett_isis_lsp_clv_is_neighbors,
167 dissect_lsp_l1_is_neighbors_clv
170 ISIS_CLV_ES_NEIGHBORS,
172 &ett_isis_lsp_clv_is_neighbors,
173 dissect_lsp_l1_es_neighbors_clv
176 ISIS_CLV_EXTD_IS_REACH,
177 "Extended IS reachability",
178 &ett_isis_lsp_clv_ext_is_reachability,
179 dissect_lsp_ext_is_reachability_clv
182 ISIS_CLV_INT_IP_REACH,
183 "IP Internal reachability",
184 &ett_isis_lsp_clv_ip_reachability,
185 dissect_lsp_ip_reachability_clv
188 ISIS_CLV_EXT_IP_REACH,
189 "IP External reachability",
190 &ett_isis_lsp_clv_ip_reachability,
191 dissect_lsp_ip_reachability_clv
194 ISIS_CLV_EXTD_IP_REACH,
195 "Extended IP Reachability",
196 &ett_isis_lsp_clv_ext_ip_reachability,
197 dissect_lsp_ext_ip_reachability_clv
202 &ett_isis_lsp_clv_ipv6_reachability,
203 dissect_lsp_ipv6_reachability_clv
206 ISIS_CLV_PROTOCOLS_SUPPORTED,
207 "Protocols supported",
208 &ett_isis_lsp_clv_nlpid,
209 dissect_lsp_nlpid_clv
214 &ett_isis_lsp_clv_hostname,
215 dissect_lsp_hostname_clv
218 ISIS_CLV_TE_ROUTER_ID,
219 "Traffic Engineering Router ID",
220 &ett_isis_lsp_clv_te_router_id,
221 dissect_lsp_te_router_id_clv
225 "IP Interface address(es)",
226 &ett_isis_lsp_clv_ipv4_int_addr,
227 dissect_lsp_ip_int_addr_clv
231 "IPv6 Interface address(es)",
232 &ett_isis_lsp_clv_ipv6_int_addr,
233 dissect_lsp_ipv6_int_addr_clv
236 ISIS_CLV_AUTHENTICATION,
238 &ett_isis_lsp_clv_authentication,
239 dissect_lsp_authentication_clv
242 ISIS_CLV_IP_AUTHENTICATION,
244 &ett_isis_lsp_clv_ip_authentication,
245 dissect_lsp_ip_authentication_clv
248 ISIS_CLV_MT_SUPPORTED,
249 "Multi Topology supported",
250 &ett_isis_lsp_clv_mt,
254 ISIS_CLV_MT_IS_REACH,
255 "Multi Topology IS Reachability",
256 &ett_isis_lsp_clv_mt_is,
257 dissect_lsp_mt_is_reachability_clv
260 ISIS_CLV_MT_IP_REACH,
261 "Multi Topology Reachable IPv4 Prefixes",
262 &ett_isis_lsp_clv_mt_reachable_IPv4_prefx,
263 dissect_lsp_mt_reachable_IPv4_prefx_clv
266 ISIS_CLV_MT_IP6_REACH,
267 "Multi Topology Reachable IPv6 Prefixes",
268 &ett_isis_lsp_clv_mt_reachable_IPv6_prefx,
269 dissect_lsp_mt_reachable_IPv6_prefx_clv
279 static const isis_clv_handle_t clv_l2_lsp_opts[] = {
281 ISIS_CLV_AREA_ADDRESS,
283 &ett_isis_lsp_clv_area_addr,
284 dissect_lsp_area_address_clv
289 &ett_isis_lsp_clv_is_neighbors,
290 dissect_lsp_l2_is_neighbors_clv
293 ISIS_CLV_EXTD_IS_REACH,
294 "Extended IS reachability",
295 &ett_isis_lsp_clv_ext_is_reachability,
296 dissect_lsp_ext_is_reachability_clv
299 ISIS_CLV_PARTITION_DIS,
300 "Parition Designated Level 2 IS",
301 &ett_isis_lsp_clv_partition_dis,
302 dissect_lsp_partition_dis_clv
305 ISIS_CLV_PREFIX_NEIGHBORS,
307 &ett_isis_lsp_clv_prefix_neighbors,
308 dissect_lsp_prefix_neighbors_clv
311 ISIS_CLV_INT_IP_REACH,
312 "IP Internal reachability",
313 &ett_isis_lsp_clv_ip_reachability,
314 dissect_lsp_ip_reachability_clv
317 ISIS_CLV_EXT_IP_REACH,
318 "IP External reachability",
319 &ett_isis_lsp_clv_ip_reachability,
320 dissect_lsp_ip_reachability_clv
323 ISIS_CLV_PROTOCOLS_SUPPORTED,
324 "Protocols supported",
325 &ett_isis_lsp_clv_nlpid,
326 dissect_lsp_nlpid_clv
331 &ett_isis_lsp_clv_hostname,
332 dissect_lsp_hostname_clv
335 ISIS_CLV_TE_ROUTER_ID,
336 "Traffic Engineering Router ID",
337 &ett_isis_lsp_clv_te_router_id,
338 dissect_lsp_te_router_id_clv
341 ISIS_CLV_EXTD_IP_REACH,
342 "Extended IP Reachability",
343 &ett_isis_lsp_clv_ext_ip_reachability,
344 dissect_lsp_ext_ip_reachability_clv
349 &ett_isis_lsp_clv_ipv6_reachability,
350 dissect_lsp_ipv6_reachability_clv
354 "IP Interface address(es)",
355 &ett_isis_lsp_clv_ipv4_int_addr,
356 dissect_lsp_ip_int_addr_clv
360 "IPv6 Interface address(es)",
361 &ett_isis_lsp_clv_ipv6_int_addr,
362 dissect_lsp_ipv6_int_addr_clv
365 ISIS_CLV_AUTHENTICATION,
367 &ett_isis_lsp_clv_authentication,
368 dissect_lsp_authentication_clv
371 ISIS_CLV_IP_AUTHENTICATION,
373 &ett_isis_lsp_clv_ip_authentication,
374 dissect_lsp_ip_authentication_clv
377 ISIS_CLV_MT_SUPPORTED,
379 &ett_isis_lsp_clv_mt,
383 ISIS_CLV_MT_IS_REACH,
384 "Multi Topology IS Reachability",
385 &ett_isis_lsp_clv_mt_is,
386 dissect_lsp_mt_is_reachability_clv
389 ISIS_CLV_MT_IP_REACH,
390 "Multi Topology Reachable IPv4 Prefixes",
391 &ett_isis_lsp_clv_mt_reachable_IPv4_prefx,
392 dissect_lsp_mt_reachable_IPv4_prefx_clv
395 ISIS_CLV_MT_IP6_REACH,
396 "Multi Topology Reachable IPv6 Prefixes",
397 &ett_isis_lsp_clv_mt_reachable_IPv6_prefx,
398 dissect_lsp_mt_reachable_IPv6_prefx_clv
409 * Name: dissect_lsp_mt_id()
412 * dissect and display the multi-topology ID value
415 * tvbuff_t * : tvbuffer for packet data
416 * proto_tree * : protocol display tree to fill out. CAN'T BE NULL
417 * int : offset into packet data where we are.
420 * void, but we will add to proto tree.
423 dissect_lsp_mt_id(tvbuff_t *tvb, proto_tree *tree, int offset)
428 /* fetch two bytes */
429 mt_block = tvb_get_ntohs(tvb, offset);
431 proto_tree_add_text ( tree, tvb, offset, 1 ,
432 "4 most significant bits reserved, should be set to 0 (%d)", ISIS_LSP_MT_MSHIP_RES(mt_block));
434 mt_id = ISIS_LSP_MT_MSHIP_ID(mt_block);
435 /*mask out the lower 12 bits */
438 strcpy(mt_desc,"'standard' topology");
441 strcpy(mt_desc,"IPv4 In-Band Management purposes");
444 strcpy(mt_desc,"IPv6 routing topology");
447 strcpy(mt_desc,"IPv4 multicast routing topology");
450 strcpy(mt_desc,"IPv6 multicast routing topology");
453 strcpy(mt_desc,((mt_block & 0x0fff) < 3996) ? "Reserved for IETF Consensus" : "Development, Experimental and Proprietary features");
456 proto_tree_add_text ( tree, tvb, offset, 2 ,
457 "%s (%d)", mt_desc, mt_id);
462 * Name: dissect_metric()
465 * Display a metric prefix portion. ISIS has the concept of multple
466 * metric per prefix (default, delay, expense, and error). This
467 * routine assists other dissectors by adding a single one of
468 * these to the display tree..
470 * The 8th(msbit) bit in the metric octet is the "supported" bit. The
471 * "default" support is required, so we support a "force_supported"
472 * flag that tells us that it MUST be zero (zero==supported,
473 * so it really should be a "not supported" in the boolean sense)
474 * and to display a protocol failure accordingly. Notably,
475 * Cisco IOS 12(6) blows this!
476 * The 7th bit must be zero (reserved).
479 * tvbuff_t * : tvbuffer for packet data
480 * proto_tree * : protocol display tree to fill out. May be NULL
481 * int : offset into packet data where we are.
482 * guint8 : value of the metric.
483 * char * : string giving type of the metric.
484 * int : force supported. True is the supported bit MUST be zero.
487 * void, but we will add to proto tree if !NULL.
490 dissect_metric(tvbuff_t *tvb, proto_tree *tree, int offset, guint8 value,
491 char *pstr, int force_supported )
497 s = ISIS_LSP_CLV_METRIC_SUPPORTED(value);
498 proto_tree_add_text(tree, tvb, offset, 1,
499 "%s Metric: %s%s %s%d:%d", pstr,
500 s ? "Not supported" : "Supported",
501 (s && force_supported) ? "(but is required to be)":"",
502 ISIS_LSP_CLV_METRIC_RESERVED(value) ? "(reserved bit != 0)":"",
503 ISIS_LSP_CLV_METRIC_VALUE(value), value );
507 * Name: dissect_lsp_ip_reachability_clv()
510 * Decode an IP reachability CLV. This can be either internal or
511 * external (the clv format does not change and which type we are
512 * displaying is put there by the dispatcher). All of these
513 * are a metric block followed by an IP addr and mask.
516 * tvbuff_t * : tvbuffer for packet data
517 * proto_tree * : proto tree to build on (may be null)
518 * int : current offset into packet data
519 * int : length of IDs in packet.
520 * int : length of this clv
523 * void, will modify proto_tree if not null.
526 dissect_lsp_ip_reachability_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
527 int id_length _U_, int length)
530 proto_tree *ntree = NULL;
531 guint32 src, mask, prefix_len;
533 guint32 bitmasks[33] = {
535 0x00000008, 0x0000000c, 0x0000000e, 0x0000000f,
536 0x000000f8, 0x000000fc, 0x000000fe, 0x000000ff,
537 0x000008ff, 0x00000cff, 0x00000eff, 0x00000fff,
538 0x0000f8ff, 0x0000fcff, 0x0000feff, 0x0000ffff,
539 0x0008ffff, 0x000cffff, 0x000effff, 0x000fffff,
540 0x00f8ffff, 0x00fcffff, 0x00feffff, 0x00ffffff,
541 0x08ffffff, 0x0cffffff, 0x0effffff, 0x0fffffff,
542 0xf8ffffff, 0xfcffffff, 0xfeffffff, 0xffffffff
546 while ( length > 0 ) {
548 isis_dissect_unknown(tvb, tree, offset,
549 "short IP reachability (%d vs 12)", length );
553 * Gotta build a sub-tree for all our pieces
556 tvb_memcpy(tvb, (guint8 *)&src, offset+4, 4);
557 tvb_memcpy(tvb, (guint8 *)&mask, offset+8, 4);
559 /* find out if the mask matches one of 33 possible prefix lengths */
563 while(prefix_len<=33) {
564 if (bitmasks[prefix_len++]==mask) {
570 /* 34 indicates no match -> must be a discontiguous netmask
571 lets dump the mask, otherwise print the prefix_len */
574 ti = proto_tree_add_text ( tree, tvb, offset, 12,
575 "IPv4 prefix: %s mask %s",
576 ip_to_str((guint8*)&src),
577 ip_to_str((guint8*)&mask));
579 ti = proto_tree_add_text ( tree, tvb, offset, 12,
580 "IPv4 prefix: %s/%d",
581 ip_to_str((guint8*)&src),
585 ntree = proto_item_add_subtree(ti,
586 ett_isis_lsp_clv_ip_reachability);
588 proto_tree_add_text (ntree, tvb, offset, 1,
589 "Default Metric: %d, %s, Distribution: %s",
590 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset)),
591 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset)) ? "External" : "Internal",
592 ISIS_LSP_CLV_METRIC_UPDOWN(tvb_get_guint8(tvb, offset)) ? "down" : "up");
595 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+1))) {
596 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: Not supported");
598 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: %d, %s",
599 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+1)),
600 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+1)) ? "External" : "Internal");
603 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+2))) {
604 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: Not supported");
606 proto_tree_add_text (ntree, tvb, offset+2, 1, "Exense Metric: %d, %s",
607 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+2)),
608 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+2)) ? "External" : "Internal");
611 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+3))) {
612 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: Not supported");
614 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: %d, %s",
615 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+3)),
616 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+3)) ? "External" : "Internal");
625 * Name: dissect_ipreach_subclv ()
627 * Description: parses IP reach subTLVs
628 * Called by various IP Reachability dissectors.
631 * tvbuff_t * : tvbuffer for packet data
632 * proto_tree * : protocol display tree to fill out.
633 * int : offset into packet data where we are (beginning of the sub_clv value).
639 dissect_ipreach_subclv(tvbuff_t *tvb, proto_tree *tree, int offset, int clv_code, int clv_len)
644 while (clv_len >= 4) {
645 proto_tree_add_text(tree, tvb, offset, 4,
646 "32-Bit Administrative tag: 0x%08x (=%u)",
647 tvb_get_ntohl(tvb, offset),
648 tvb_get_ntohl(tvb, offset));
654 while (clv_len >= 8) {
655 proto_tree_add_text(tree, tvb, offset, 8,
656 "64-Bit Administrative tag: 0x%08x%08x",
657 tvb_get_ntohl(tvb, offset),
658 tvb_get_ntohl(tvb, offset+4));
665 proto_tree_add_text (tree, tvb, offset, clv_len+2,
666 "Unknown sub-TLV: code %u, length %u",
674 * Name: dissect_lsp_ext_ip_reachability_clv()
676 * Description: Decode an Extended IP Reachability CLV - code 135.
678 * The extended IP reachability TLV is an extended version
679 * of the IP reachability TLVs (codes 128 and 130). It encodes
680 * the metric as a 32-bit unsigned interger and allows to add
683 * CALLED BY TLV 235 DISSECTOR
687 * tvbuff_t * : tvbuffer for packet data
688 * proto_tree * : proto tree to build on (may be null)
689 * int : current offset into packet data
690 * int : length of IDs in packet.
691 * int : length of this clv
694 * void, will modify proto_tree if not null.
697 dissect_lsp_ext_ip_reachability_clv(tvbuff_t *tvb, proto_tree *tree,
698 int offset, int id_length _U_, int length)
700 proto_item *pi = NULL;
701 proto_tree *subtree = NULL;
702 proto_tree *subtree2 = NULL;
704 guint8 bit_length, byte_length;
709 guint8 clv_code, clv_len;
714 memset (prefix, 0, 4);
715 ctrl_info = tvb_get_guint8(tvb, offset+4);
716 bit_length = ctrl_info & 0x3f;
717 byte_length = (bit_length + 7) / 8;
718 if (byte_length > sizeof(prefix)) {
719 isis_dissect_unknown(tvb, tree, offset,
720 "IPv4 prefix has an invalid length: %d bytes", byte_length );
723 tvb_memcpy (tvb, prefix, offset+5, byte_length);
724 metric = tvb_get_ntohl(tvb, offset);
726 if ((ctrl_info & 0x40) != 0)
727 subclvs_len = 1+tvb_get_guint8(tvb, offset+5+byte_length);
729 pi = proto_tree_add_text (tree, tvb, offset, 5+byte_length+subclvs_len,
730 "IPv4 prefix: %s/%d, Metric: %u, Distribution: %s, %ssub-TLVs present",
734 ((ctrl_info & 0x80) == 0) ? "up" : "down",
735 ((ctrl_info & 0x40) == 0) ? "no " : "" );
737 /* open up a new tree per prefix */
738 subtree = proto_item_add_subtree (pi, ett_isis_lsp_part_of_clv_ext_ip_reachability);
740 proto_tree_add_text (subtree, tvb, offset+5, byte_length, "IPv4 prefix: %s/%u",
744 proto_tree_add_text (subtree, tvb, offset, 4, "Metric: %u", metric);
746 proto_tree_add_text (subtree, tvb, offset+4, 1, "Distribution: %s",
747 ((ctrl_info & 0x80) == 0) ? "up" : "down");
749 len = 5 + byte_length;
750 if ((ctrl_info & 0x40) != 0) {
751 subclvs_len = tvb_get_guint8(tvb, offset+len);
752 pi = proto_tree_add_text (subtree, tvb, offset+len, 1, "sub-TLVs present, total length: %u bytes",
754 proto_item_set_len (pi, subclvs_len+1);
755 /* open up a new tree for the subTLVs */
756 subtree2 = proto_item_add_subtree (pi, ett_isis_lsp_clv_ip_reach_subclv);
759 while (i < subclvs_len) {
760 clv_code = tvb_get_guint8(tvb, offset+len+1); /* skip the total subtlv len indicator */
761 clv_len = tvb_get_guint8(tvb, offset+len+2);
764 * we pass on now the raw data to the ipreach_subtlv dissector
765 * therefore we need to skip 3 bytes
766 * (total subtlv len, subtlv type, subtlv len)
768 dissect_ipreach_subclv(tvb, subtree2, offset+len+3, clv_code, clv_len);
771 len += 1 + subclvs_len;
773 proto_tree_add_text (subtree, tvb, offset+4, 1, "no sub-TLVs present");
774 proto_item_set_len (pi, len);
783 * Name: dissect_lsp_ipv6_reachability_clv()
785 * Description: Decode an IPv6 reachability CLV - code 236.
787 * CALLED BY TLV 237 DISSECTOR
790 * tvbuff_t * : tvbuffer for packet data
791 * proto_tree * : proto tree to build on (may be null)
792 * int : current offset into packet data
793 * int : length of IDs in packet.
794 * int : length of this clv
797 * void, will modify proto_tree if not null.
800 dissect_lsp_ipv6_reachability_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
801 int id_length _U_, int length)
804 proto_tree *subtree = NULL;
805 proto_tree *subtree2 = NULL;
807 guint8 bit_length, byte_length;
808 struct e_in6_addr prefix;
812 guint8 clv_code, clv_len;
817 memset (prefix.s6_addr, 0, 16);
818 ctrl_info = tvb_get_guint8(tvb, offset+4);
819 bit_length = tvb_get_guint8(tvb, offset+5);
820 byte_length = (bit_length + 7) / 8;
821 if (byte_length > sizeof(prefix)) {
822 isis_dissect_unknown(tvb, tree, offset,
823 "IPv6 prefix has an invalid length: %d bytes", byte_length );
826 tvb_memcpy (tvb, prefix.s6_addr, offset+6, byte_length);
827 metric = tvb_get_ntohl(tvb, offset);
829 if ((ctrl_info & 0x20) != 0)
830 subclvs_len = 1+tvb_get_guint8(tvb, offset+6+byte_length);
832 pi = proto_tree_add_text (tree, tvb, offset, 6+byte_length+subclvs_len,
833 "IPv6 prefix: %s/%u, Metric: %u, Distribution: %s, %s, %ssub-TLVs present",
834 ip6_to_str (&prefix),
837 ((ctrl_info & 0x80) == 0) ? "up" : "down",
838 ((ctrl_info & 0x40) == 0) ? "internal" : "external",
839 ((ctrl_info & 0x20) == 0) ? "no " : "" );
841 subtree = proto_item_add_subtree (pi, ett_isis_lsp_part_of_clv_ipv6_reachability);
843 proto_tree_add_text (subtree, tvb, offset+6, byte_length, "IPv6 prefix: %s/%u",
844 ip6_to_str (&prefix),
847 proto_tree_add_text (subtree, tvb, offset, 4,
848 "Metric: %u", metric);
850 proto_tree_add_text (subtree, tvb, offset+4, 1,
851 "Distribution: %s, %s",
852 ((ctrl_info & 0x80) == 0) ? "up" : "down",
853 ((ctrl_info & 0x40) == 0) ? "internal" : "external" );
855 if ((ctrl_info & 0x1f) != 0) {
856 proto_tree_add_text (subtree, tvb, offset+4, 1,
857 "Reserved bits: 0x%x",
858 (ctrl_info & 0x1f) );
861 len = 6 + byte_length;
862 if ((ctrl_info & 0x20) != 0) {
863 subclvs_len = tvb_get_guint8(tvb, offset+len);
864 pi = proto_tree_add_text (subtree, tvb, offset+len, 1, "sub-TLVs present, total length: %u bytes",
866 proto_item_set_len (pi, subclvs_len+1);
867 /* open up a new tree for the subTLVs */
868 subtree2 = proto_item_add_subtree (pi, ett_isis_lsp_clv_ip_reach_subclv);
871 while (i < subclvs_len) {
872 clv_code = tvb_get_guint8(tvb, offset+len+1); /* skip the total subtlv len indicator */
873 clv_len = tvb_get_guint8(tvb, offset+len+2);
874 dissect_ipreach_subclv(tvb, subtree2, offset+len+3, clv_code, clv_len);
877 len += 1 + subclvs_len;
879 proto_tree_add_text (subtree, tvb, offset+4, 1, "no sub-TLVs present");
880 proto_item_set_len (pi, len);
888 * Name: dissect_lsp_nlpid_clv()
891 * Decode for a lsp packets NLPID clv. Calls into the
895 * tvbuff_t * : tvbuffer for packet data
896 * proto_tree * : proto tree to build on (may be null)
897 * int : current offset into packet data
898 * int : length of IDs in packet.
899 * int : length of this clv
902 * void, will modify proto_tree if not null.
905 dissect_lsp_nlpid_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
906 int id_length _U_, int length)
908 isis_dissect_nlpid_clv(tvb, tree, offset, length);
912 * Name: dissect_lsp_mt_clv()
914 * Description: - code 229
915 * Decode for a lsp packets Multi Topology clv. Calls into the
919 * tvbuff_t * : tvbuffer for packet data
920 * proto_tree * : proto tree to build on (may be null)
921 * int : current offset into packet data
922 * guint : length of this clv
923 * int : length of IDs in packet.
926 * void, will modify proto_tree if not null.
929 dissect_lsp_mt_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
930 int id_length _U_, int length)
932 isis_dissect_mt_clv(tvb, tree, offset, length, hf_isis_lsp_clv_mt );
936 * Name: dissect_lsp_hostname_clv()
939 * Decode for a lsp packets hostname clv. Calls into the
943 * tvbuff_t * : tvbuffer for packet data
944 * proto_tree * : proto tree to build on (may be null)
945 * int : current offset into packet data
946 * int : length of IDs in packet.
947 * int : length of this clv
950 * void, will modify proto_tree if not null.
953 dissect_lsp_hostname_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
954 int id_length _U_, int length)
956 isis_dissect_hostname_clv(tvb, tree, offset, length);
961 * Name: dissect_lsp_te_router_id_clv()
964 * Decode for a lsp packets Traffic Engineering ID clv. Calls into the
968 * tvbuff_t * : tvbuffer for packet data
969 * proto_tree * : proto tree to build on (may be null)
970 * int : current offset into packet data
971 * int : length of IDs in packet.
972 * int : length of this clv
975 * void, will modify proto_tree if not null.
978 dissect_lsp_te_router_id_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
979 int id_length _U_, int length)
981 isis_dissect_te_router_id_clv(tvb, tree, offset, length,
982 hf_isis_lsp_clv_te_router_id );
987 * Name: dissect_lsp_ip_int_addr_clv()
990 * Decode for a lsp packets ip interface addr clv. Calls into the
994 * tvbuff_t * : tvbuffer for packet data
995 * proto_tree * : proto tree to build on (may be null)
996 * int : current offset into packet data
997 * int : length of IDs in packet.
998 * int : length of this clv
1001 * void, will modify proto_tree if not null.
1004 dissect_lsp_ip_int_addr_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1005 int id_length _U_, int length)
1007 isis_dissect_ip_int_clv(tvb, tree, offset, length,
1008 hf_isis_lsp_clv_ipv4_int_addr );
1012 * Name: dissect_lsp_ipv6_int_addr_clv()
1014 * Description: Decode an IPv6 interface addr CLV - code 232.
1016 * Calls into the clv common one.
1019 * tvbuff_t * : tvbuffer for packet data
1020 * proto_tree * : proto tree to build on (may be null)
1021 * int : current offset into packet data
1022 * int : length of IDs in packet.
1023 * int : length of this clv
1026 * void, will modify proto_tree if not null.
1029 dissect_lsp_ipv6_int_addr_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1030 int id_length _U_, int length)
1032 isis_dissect_ipv6_int_clv(tvb, tree, offset, length,
1033 hf_isis_lsp_clv_ipv6_int_addr );
1037 * Name: dissect_lsp_authentication_clv()
1040 * Decode for a lsp packets authenticaion clv. Calls into the
1044 * tvbuff_t * : tvbuffer for packet data
1045 * proto_tree * : proto tree to build on (may be null)
1046 * int : current offset into packet data
1047 * int : length of IDs in packet.
1048 * int : length of this clv
1051 * void, will modify proto_tree if not null.
1054 dissect_lsp_authentication_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1055 int id_length _U_, int length)
1057 isis_dissect_authentication_clv(tvb, tree, offset, length);
1061 * Name: dissect_lsp_ip_authentication_clv()
1064 * Decode for a lsp packets authenticaion clv. Calls into the
1068 * tvbuff_t * : tvbuffer for packet data
1069 * proto_tree * : proto tree to build on (may be null)
1070 * int : current offset into packet data
1071 * int : length of IDs in packet.
1072 * int : length of this clv
1075 * void, will modify proto_tree if not null.
1078 dissect_lsp_ip_authentication_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1079 int id_length _U_, int length)
1081 isis_dissect_ip_authentication_clv(tvb, tree, offset, length);
1085 * Name: dissect_lsp_area_address_clv()
1088 * Decode for a lsp packet's area address clv. Call into clv common
1092 * tvbuff_t * : tvbuffer for packet data
1093 * proto_tree * : protocol display tree to fill out. May be NULL
1094 * int : offset into packet data where we are.
1095 * int : length of IDs in packet.
1096 * int : length of clv we are decoding
1099 * void, but we will add to proto tree if !NULL.
1102 dissect_lsp_area_address_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1103 int id_length _U_, int length)
1105 isis_dissect_area_address_clv(tvb, tree, offset, length);
1109 * Name: dissect_lsp_eis_neighbors_clv_inner()
1112 * Real work horse for showing neighbors. This means we decode the
1113 * first octet as either virtual/!virtual (if show_virtual param is
1114 * set), or as a must == 0 reserved value.
1116 * Once past that, we decode n neighbor elements. Each neighbor
1117 * is comprised of a metric block (is dissect_metric) and the
1121 * tvbuff_t * : tvbuffer for packet data
1122 * proto_tree * : protocol display tree to fill out. May be NULL
1123 * int : offset into packet data where we are.
1124 * int : length of IDs in packet.
1125 * int : length of clv we are decoding
1126 * int : set to decode first octet as virtual vs reserved == 0
1127 * int : set to indicate EIS instead of IS (6 octet per addr instead of 7)
1130 * void, but we will add to proto tree if !NULL.
1133 dissect_lsp_eis_neighbors_clv_inner(tvbuff_t *tvb, proto_tree *tree,
1134 int offset, int length, int id_length, int show_virtual, int is_eis)
1137 proto_tree *ntree = NULL;
1141 id_length++; /* IDs are one octet longer in IS neighbours */
1143 if ( show_virtual ) {
1144 /* virtual path flag */
1145 proto_tree_add_text ( tree, tvb, offset, 1,
1146 tvb_get_guint8(tvb, offset) ? "IsVirtual" : "IsNotVirtual" );
1148 proto_tree_add_text ( tree, tvb, offset, 1,
1149 "Reserved value 0x%02x, must == 0",
1150 tvb_get_guint8(tvb, offset) );
1156 tlen = 4 + id_length;
1158 while ( length > 0 ) {
1160 isis_dissect_unknown(tvb, tree, offset,
1161 "short E/IS reachability (%d vs %d)", length,
1166 * Gotta build a sub-tree for all our pieces
1170 ti = proto_tree_add_text(tree, tvb, offset, tlen,
1172 print_system_id( tvb_get_ptr(tvb, offset+4, id_length), id_length ) );
1174 ti = proto_tree_add_text(tree, tvb, offset, tlen,
1176 print_system_id(tvb_get_ptr(tvb, offset+4, id_length), id_length ) );
1178 ntree = proto_item_add_subtree(ti,
1179 ett_isis_lsp_clv_is_neighbors);
1183 proto_tree_add_text (ntree, tvb, offset, 1,
1184 "Default Metric: %d, %s",
1185 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset)),
1186 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset)) ? "External" : "Internal");
1188 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+1))) {
1189 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: Not supported");
1191 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: %d, %s",
1192 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+1)),
1193 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+1)) ? "External" : "Internal");
1197 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+2))) {
1198 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: Not supported");
1200 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: %d, %s",
1201 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+2)),
1202 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+2)) ? "External" : "Internal");
1205 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+3))) {
1206 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: Not supported");
1208 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: %d, %s",
1209 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+3)),
1210 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+3)) ? "External" : "Internal");
1220 * Name: dissect_lsp_l1_is_neighbors_clv()
1223 * Dispatch a l1 intermediate system neighbor by calling
1224 * the inner function with show virtual set to TRUE and is es set to FALSE.
1227 * tvbuff_t * : tvbuffer for packet data
1228 * proto_tree * : protocol display tree to fill out. May be NULL
1229 * int : offset into packet data where we are.
1230 * int : length of IDs in packet.
1231 * int : length of clv we are decoding
1234 * void, but we will add to proto tree if !NULL.
1237 dissect_lsp_l1_is_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1238 int id_length, int length)
1240 dissect_lsp_eis_neighbors_clv_inner(tvb, tree, offset,
1241 length, id_length, TRUE, FALSE);
1245 * Name: dissect_lsp_l1_es_neighbors_clv()
1248 * Dispatch a l1 end or intermediate system neighbor by calling
1249 * the inner function with show virtual set to TRUE and es set to TRUE.
1252 * tvbuff_t * : tvbuffer for packet data
1253 * proto_tree * : protocol display tree to fill out. May be NULL
1254 * int : offset into packet data where we are.
1255 * int : length of IDs in packet.
1256 * int : length of clv we are decoding
1259 * void, but we will add to proto tree if !NULL.
1262 dissect_lsp_l1_es_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1263 int id_length, int length)
1265 dissect_lsp_eis_neighbors_clv_inner(tvb, tree, offset,
1266 length, id_length, TRUE, TRUE);
1270 * Name: dissect_lsp_l2_is_neighbors_clv()
1273 * Dispatch a l2 intermediate system neighbor by calling
1274 * the inner function with show virtual set to FALSE, and is es set
1278 * tvbuff_t * : tvbuffer for packet data
1279 * proto_tree * : protocol display tree to fill out. May be NULL
1280 * int : offset into packet data where we are.
1281 * int : length of IDs in packet.
1282 * int : length of clv we are decoding
1285 * void, but we will add to proto tree if !NULL.
1288 dissect_lsp_l2_is_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1289 int id_length, int length)
1291 dissect_lsp_eis_neighbors_clv_inner(tvb, tree, offset,
1292 length, id_length, FALSE, FALSE);
1297 * Name: dissect_subclv_admin_group ()
1299 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1301 * This function is called by dissect_lsp_ext_is_reachability_clv()
1302 * for dissect the administrive group sub-CLV (code 3).
1305 * tvbuff_t * : tvbuffer for packet data
1306 * proto_tree * : protocol display tree to fill out.
1307 * int : offset into packet data where we are (beginning of the sub_clv value).
1313 dissect_subclv_admin_group (tvbuff_t *tvb, proto_tree *tree, int offset) {
1320 ti = proto_tree_add_text(tree, tvb, offset-2, 6, "Administrative group(s):");
1321 ntree = proto_item_add_subtree (ti, ett_isis_lsp_subclv_admin_group);
1323 clv_value = tvb_get_ntohl(tvb, offset);
1325 for (i = 0 ; i < 32 ; i++) {
1326 if ( (clv_value & mask) != 0 ) {
1327 proto_tree_add_text (ntree, tvb, offset, 4, "group %d", i);
1334 * Name: dissect_subclv_max_bw ()
1336 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1338 * This function is called by dissect_lsp_ext_is_reachability_clv()
1339 * for dissect the maximum link bandwidth sub-CLV (code 9).
1342 * tvbuff_t * : tvbuffer for packet data
1343 * proto_tree * : protocol display tree to fill out.
1344 * int : offset into packet data where we are (beginning of the sub_clv value).
1350 dissect_subclv_max_bw(tvbuff_t *tvb, proto_tree *tree, int offset)
1354 bw = tvb_get_ntohieee_float(tvb, offset);
1355 proto_tree_add_text (tree, tvb, offset-2, 6,
1356 "Maximum link bandwidth : %.2f Mbps", bw*8/1000000 );
1360 * Name: dissect_subclv_rsv_bw ()
1362 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1364 * This function is called by dissect_lsp_ext_is_reachability_clv()
1365 * for dissect the reservable link bandwidth sub-CLV (code 10).
1368 * tvbuff_t * : tvbuffer for packet data
1369 * proto_tree * : protocol display tree to fill out.
1370 * int : offset into packet data where we are (beginning of the sub_clv value).
1376 dissect_subclv_rsv_bw(tvbuff_t *tvb, proto_tree *tree, int offset)
1380 bw = tvb_get_ntohieee_float(tvb, offset);
1381 proto_tree_add_text (tree, tvb, offset-2, 6,
1382 "Reservable link bandwidth: %.2f Mbps", bw*8/1000000 );
1386 * Name: dissect_subclv_unrsv_bw ()
1388 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1390 * This function is called by dissect_lsp_ext_is_reachability_clv()
1391 * for dissect the unreserved bandwidth sub-CLV (code 11).
1394 * tvbuff_t * : tvbuffer for packet data
1395 * proto_tree * : protocol display tree to fill out.
1396 * int : offset into packet data where we are (beginning of the sub_clv value).
1402 dissect_subclv_unrsv_bw(tvbuff_t *tvb, proto_tree *tree, int offset)
1409 ti = proto_tree_add_text (tree, tvb, offset-2, 34, "Unreserved bandwidth:");
1410 ntree = proto_item_add_subtree (ti, ett_isis_lsp_subclv_unrsv_bw);
1412 for (i = 0 ; i < 8 ; i++) {
1413 bw = tvb_get_ntohieee_float(tvb, offset+4*i);
1414 proto_tree_add_text (ntree, tvb, offset+4*i, 4,
1415 "priority level %d: %.2f Mbps", i, bw*8/1000000 );
1420 * Name: dissect_lsp_ext_is_reachability_clv()
1422 * Description: Decode a Extended IS Reachability CLV - code 22
1424 * The extended IS reachability TLV is an extended version
1425 * of the IS reachability TLV (code 2). It encodes the metric
1426 * as a 24-bit unsigned interger and allows to add sub-CLV(s).
1428 * CALLED BY TLV 222 DISSECTOR
1431 * tvbuff_t * : tvbuffer for packet data
1432 * proto_tree * : protocol display tree to fill out. May be NULL
1433 * int : offset into packet data where we are.
1434 * int : length of IDs in packet.
1435 * int : length of clv we are decoding
1438 * void, but we will add to proto tree if !NULL.
1441 dissect_lsp_ext_is_reachability_clv(tvbuff_t *tvb, proto_tree *tree,
1442 int offset, int id_length _U_, int length)
1445 proto_tree *ntree = NULL;
1448 guint8 clv_code, clv_len;
1452 while (length > 0) {
1453 ti = proto_tree_add_text (tree, tvb, offset, -1,
1455 print_system_id (tvb_get_ptr(tvb, offset, 7), 7) );
1456 ntree = proto_item_add_subtree (ti,
1457 ett_isis_lsp_part_of_clv_ext_is_reachability );
1459 proto_tree_add_text (ntree, tvb, offset+7, 3,
1460 "Metric: %d", tvb_get_ntoh24(tvb, offset+7) );
1462 subclvs_len = tvb_get_guint8(tvb, offset+10);
1463 if (subclvs_len == 0) {
1464 proto_tree_add_text (ntree, tvb, offset+10, 1, "no sub-TLVs present");
1468 while (i < subclvs_len) {
1469 clv_code = tvb_get_guint8(tvb, offset+11+i);
1470 clv_len = tvb_get_guint8(tvb, offset+12+i);
1473 dissect_subclv_admin_group(tvb, ntree, offset+13+i);
1476 proto_tree_add_text (ntree, tvb, offset+11+i, 6,
1477 "IPv4 interface address: %s", ip_to_str (tvb_get_ptr(tvb, offset+13+i, 4)) );
1480 proto_tree_add_text (ntree, tvb, offset+11+i, 6,
1481 "IPv4 neighbor address: %s", ip_to_str (tvb_get_ptr(tvb, offset+13+i, 4)) );
1484 dissect_subclv_max_bw (tvb, ntree, offset+13+i);
1487 dissect_subclv_rsv_bw (tvb, ntree, offset+13+i);
1490 dissect_subclv_unrsv_bw (tvb, ntree, offset+13+i);
1493 proto_tree_add_text (ntree, tvb, offset+11+i, 5,
1494 "Traffic engineering default metric: %d",
1495 tvb_get_ntoh24(tvb, offset+13+i) );
1502 proto_tree_add_text (ntree, tvb, offset+11+i, clv_len+2,
1503 "Unknown Cisco specific extensions: code %d, length %d",
1504 clv_code, clv_len );
1507 proto_tree_add_text (ntree, tvb, offset+11+i, clv_len+2,
1508 "Unknown sub-CLV: code %d, length %d", clv_code, clv_len );
1515 len = 11 + subclvs_len;
1516 proto_item_set_len (ti, len);
1523 * Name: dissect_lsp_mt_reachable_IPv4_prefx_clv()
1525 * Description: Decode Multi-Topology IPv4 Prefixes - code 235
1529 * tvbuff_t * : tvbuffer for packet data
1530 * proto_tree * : protocol display tree to fill out. May be NULL
1531 * int : offset into packet data where we are.
1532 * int : length of IDs in packet.
1533 * int : length of clv we are decoding
1536 * void, but we will add to proto tree if !NULL.
1539 dissect_lsp_mt_reachable_IPv4_prefx_clv(tvbuff_t *tvb,
1540 proto_tree *tree, int offset, int id_length _U_, int length)
1544 isis_dissect_unknown(tvb, tree, offset,
1545 "short lsp multi-topology reachable IPv4 prefixes(%d vs %d)", length,
1549 dissect_lsp_mt_id(tvb, tree, offset);
1550 dissect_lsp_ext_ip_reachability_clv(tvb, tree, offset+2, 0, length-2);
1554 * Name: dissect_lsp_mt_reachable_IPv6_prefx_clv()
1556 * Description: Decode Multi-Topology IPv6 Prefixes - code 237
1560 * tvbuff_t * : tvbuffer for packet data
1561 * proto_tree * : protocol display tree to fill out. May be NULL
1562 * int : offset into packet data where we are.
1563 * int : length of IDs in packet.
1564 * int : length of clv we are decoding
1567 * void, but we will add to proto tree if !NULL.
1570 dissect_lsp_mt_reachable_IPv6_prefx_clv(tvbuff_t *tvb,
1571 proto_tree *tree, int offset, int id_length _U_, int length)
1575 isis_dissect_unknown(tvb, tree, offset,
1576 "short lsp multi-topology reachable IPv6 prefixes(%d vs %d)", length,
1580 dissect_lsp_mt_id(tvb, tree, offset);
1581 dissect_lsp_ipv6_reachability_clv(tvb, tree, offset+2, 0, length-2);
1586 * Name: dissect_lsp_mt_is_reachability_clv()
1588 * Description: Decode Multi-Topology Intermediate Systems - code 222
1592 * tvbuff_t * : tvbuffer for packet data
1593 * proto_tree * : protocol display tree to fill out. May be NULL
1594 * int : offset into packet data where we are.
1596 * int : length of clv we are decoding
1599 * void, but we will add to proto tree if !NULL.
1603 dissect_lsp_mt_is_reachability_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1604 int id_length _U_, int length)
1608 isis_dissect_unknown(tvb, tree, offset,
1609 "short lsp reachability(%d vs %d)", length,
1615 * the MT ID value dissection is used in other LSPs so we push it
1618 dissect_lsp_mt_id(tvb, tree, offset);
1620 * fix here. No need to parse TLV 22 (with bugs) while it is
1621 * already done correctly!!
1623 dissect_lsp_ext_is_reachability_clv(tvb, tree, offset+2, 0, length-2);
1627 * Name: dissect_lsp_partition_dis_clv()
1630 * This CLV is used to indicate which system is the designated
1631 * IS for partition repair. This means just putting out the
1632 * "id_length"-octet IS.
1635 * tvbuff_t * : tvbuffer for packet data
1636 * proto_tree * : protocol display tree to fill out. May be NULL
1637 * int : offset into packet data where we are.
1638 * int : length of IDs in packet.
1639 * int : length of clv we are decoding
1642 * void, but we will add to proto tree if !NULL.
1645 dissect_lsp_partition_dis_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1646 int id_length, int length)
1648 if ( length < id_length ) {
1649 isis_dissect_unknown(tvb, tree, offset,
1650 "short lsp partition DIS(%d vs %d)", length,
1655 * Gotta build a sub-tree for all our pieces
1658 proto_tree_add_text ( tree, tvb, offset, id_length,
1659 "Partition designated L2 IS: %s",
1660 print_system_id( tvb_get_ptr(tvb, offset, id_length), id_length ) );
1662 length -= id_length;
1663 offset += id_length;
1665 isis_dissect_unknown(tvb, tree, offset,
1666 "Long lsp partition DIS, %d left over", length );
1672 * Name: dissect_lsp_prefix_neighbors_clv()
1675 * The prefix CLV describes what other (OSI) networks we can reach
1676 * and what their cost is. It is built from a metric block
1677 * (see dissect_metric) followed by n addresses.
1680 * tvbuff_t * : tvbuffer for packet data
1681 * proto_tree * : protocol display tree to fill out. May be NULL
1682 * int : offset into packet data where we are.
1683 * int : length of IDs in packet.
1684 * int : length of clv we are decoding
1687 * void, but we will add to proto tree if !NULL.
1690 dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1691 int id_length _U_, int length)
1697 isis_dissect_unknown(tvb, tree, offset,
1698 "Short lsp prefix neighbors (%d vs 4)", length );
1702 dissect_metric (tvb, tree, offset,
1703 tvb_get_guint8(tvb, offset), "Default", TRUE );
1704 dissect_metric (tvb, tree, offset+1,
1705 tvb_get_guint8(tvb, offset+1), "Delay", FALSE );
1706 dissect_metric (tvb, tree, offset+2,
1707 tvb_get_guint8(tvb, offset+2), "Expense", FALSE );
1708 dissect_metric (tvb, tree, offset+3,
1709 tvb_get_guint8(tvb, offset+3), "Error", FALSE );
1713 while ( length > 0 ) {
1714 mylen = tvb_get_guint8(tvb, offset);
1717 isis_dissect_unknown(tvb, tree, offset,
1718 "Zero payload space after length in prefix neighbor" );
1721 if ( mylen > length) {
1722 isis_dissect_unknown(tvb, tree, offset,
1723 "Interal length of prefix neighbor too long (%d vs %d)",
1729 * Lets turn the area address into "standard" 0000.0000.etc
1732 sbuf = print_area( tvb_get_ptr(tvb, offset+1, mylen), mylen );
1733 /* and spit it out */
1735 proto_tree_add_text ( tree, tvb, offset, mylen + 1,
1736 "Area address (%d): %s", mylen, sbuf );
1738 offset += mylen + 1;
1739 length -= mylen; /* length already adjusted for len fld*/
1744 * Name: isis_dissect_isis_lsp()
1747 * Print out the LSP part of the main header and then call the CLV
1748 * de-mangler with the right list of valid CLVs.
1751 * tvbuff_t * : tvbuffer for packet data
1752 * proto_tree * : protocol display tree to add to. May be NULL.
1753 * int offset : our offset into packet data.
1754 * int : LSP type, a la packet-isis.h ISIS_TYPE_* values
1755 * int : header length of packet.
1756 * int : length of IDs in packet.
1759 * void, but we will add to proto tree if !NULL.
1762 isis_dissect_isis_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
1763 int lsp_type, int header_length, int id_length)
1765 proto_item *ti, *to, *ta;
1766 proto_tree *lsp_tree = NULL, *info_tree, *att_tree;
1767 guint16 pdu_length, checksum, cacl_checksum=0;
1768 guint8 lsp_info, lsp_att;
1769 int len, offset_checksum;
1772 ti = proto_tree_add_text(tree, tvb, offset, -1,
1774 lsp_tree = proto_item_add_subtree(ti, ett_isis_lsp);
1777 pdu_length = tvb_get_ntohs(tvb, offset);
1779 proto_tree_add_uint(lsp_tree, hf_isis_lsp_pdu_length, tvb,
1780 offset, 2, pdu_length);
1785 proto_tree_add_text(lsp_tree, tvb, offset, 2,
1786 "Remaining Lifetime: %us",
1787 tvb_get_ntohs(tvb, offset));
1790 offset_checksum = offset;
1793 proto_tree_add_text(lsp_tree, tvb, offset, id_length + 2,
1795 print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) );
1798 if (check_col(pinfo->cinfo, COL_INFO)) {
1799 col_append_fstr(pinfo->cinfo, COL_INFO, ", LSP-ID: %s",
1800 print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) );
1802 offset += id_length + 2;
1805 proto_tree_add_uint(lsp_tree, hf_isis_lsp_sequence_number, tvb,
1807 tvb_get_ntohl(tvb, offset));
1809 if (check_col(pinfo->cinfo, COL_INFO)) {
1810 col_append_fstr(pinfo->cinfo, COL_INFO, ", Sequence: 0x%08x, Lifetime: %5us",
1811 tvb_get_ntohl(tvb, offset),
1812 tvb_get_ntohs(tvb, offset - (id_length+2+2)));
1817 checksum = tvb_get_ntohs(tvb, offset);
1818 switch (check_and_get_checksum(tvb, offset_checksum, pdu_length-12, checksum, offset, &cacl_checksum))
1822 proto_tree_add_uint_format(lsp_tree, hf_isis_lsp_checksum, tvb, offset, 2, checksum,
1823 "Checksum: 0x%04x (unused)", checksum);
1826 isis_dissect_unknown(tvb, tree, offset,
1827 "packet length %d went beyond packet",
1828 tvb_length_remaining(tvb, offset_checksum));
1831 proto_tree_add_uint_format(lsp_tree, hf_isis_lsp_checksum, tvb, offset, 2, checksum,
1832 "Checksum: 0x%04x (incorrect, should be 0x%04x)",
1833 checksum, cacl_checksum);
1834 proto_tree_add_boolean_hidden(lsp_tree, hf_isis_lsp_checksum_bad,
1835 tvb, offset, 2, TRUE);
1838 proto_tree_add_uint_format(lsp_tree, hf_isis_lsp_checksum, tvb, offset, 2, checksum,
1839 "Checksum: 0x%04x (correct)", checksum);
1840 proto_tree_add_boolean_hidden(lsp_tree, hf_isis_lsp_checksum_bad,
1841 tvb, offset, 2, FALSE);
1844 g_message("'check_and_get_checksum' returned an invalid value");
1851 * P | ATT | HIPPITY | IS TYPE description.
1853 lsp_info = tvb_get_guint8(tvb, offset);
1854 to = proto_tree_add_text(lsp_tree, tvb, offset, 1,
1855 "Type block(0x%02x): Partition Repair:%d, Attached bits:%d, Overload bit:%d, IS type:%d",
1857 ISIS_LSP_PARTITION(lsp_info),
1858 ISIS_LSP_ATT(lsp_info),
1859 ISIS_LSP_HIPPITY(lsp_info),
1860 ISIS_LSP_IS_TYPE(lsp_info)
1863 info_tree = proto_item_add_subtree(to, ett_isis_lsp_info);
1864 proto_tree_add_boolean(info_tree, hf_isis_lsp_p, tvb, offset, 1, lsp_info);
1865 ta = proto_tree_add_uint(info_tree, hf_isis_lsp_att, tvb, offset, 1, lsp_info);
1866 att_tree = proto_item_add_subtree(ta, ett_isis_lsp_att);
1867 lsp_att = ISIS_LSP_ATT(lsp_info);
1868 proto_tree_add_text(att_tree, tvb, offset, 1,
1869 "%d... = Error metric: %s", ISIS_LSP_ATT_ERROR(lsp_att), ISIS_LSP_ATT_ERROR(lsp_att) ? "Set" : "Unset");
1870 proto_tree_add_text(att_tree, tvb, offset, 1,
1871 ".%d.. = Expense metric: %s", ISIS_LSP_ATT_EXPENSE(lsp_att), ISIS_LSP_ATT_EXPENSE(lsp_att) ? "Set" : "Unset");
1872 proto_tree_add_text(att_tree, tvb, offset, 1,
1873 "..%d. = Delay metric: %s", ISIS_LSP_ATT_DELAY(lsp_att), ISIS_LSP_ATT_DELAY(lsp_att) ? "Set" : "Unset");
1874 proto_tree_add_text(att_tree, tvb, offset, 1,
1875 "...%d = Default metric: %s", ISIS_LSP_ATT_DEFAULT(lsp_att), ISIS_LSP_ATT_DEFAULT(lsp_att) ? "Set" : "Unset");
1876 proto_tree_add_boolean(info_tree, hf_isis_lsp_hippity, tvb, offset, 1, lsp_info);
1877 proto_tree_add_uint(info_tree, hf_isis_lsp_is_type, tvb, offset, 1, lsp_info);
1881 len = pdu_length - header_length;
1883 isis_dissect_unknown(tvb, tree, offset,
1884 "packet header length %d went beyond packet",
1889 * Now, we need to decode our CLVs. We need to pass in
1890 * our list of valid ones!
1892 if (lsp_type == ISIS_TYPE_L1_LSP){
1893 isis_dissect_clvs(tvb, lsp_tree, offset,
1894 clv_l1_lsp_opts, len, id_length,
1895 ett_isis_lsp_clv_unknown );
1897 isis_dissect_clvs(tvb, lsp_tree, offset,
1898 clv_l2_lsp_opts, len, id_length,
1899 ett_isis_lsp_clv_unknown );
1903 * Name: isis_register_lsp()
1906 * Register our protocol sub-sets with protocol manager.
1909 * int : protocol index for the ISIS protocol
1915 isis_register_lsp(int proto_isis) {
1916 static hf_register_info hf[] = {
1917 { &hf_isis_lsp_pdu_length,
1918 { "PDU length", "isis.lsp.pdu_length", FT_UINT16,
1919 BASE_DEC, NULL, 0x0, "", HFILL }},
1921 { &hf_isis_lsp_remaining_life,
1922 { "Remaining lifetime", "isis.lsp.remaining_life", FT_UINT16,
1923 BASE_DEC, NULL, 0x0, "", HFILL }},
1925 { &hf_isis_lsp_sequence_number,
1926 { "Sequence number", "isis.lsp.sequence_number",
1927 FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1929 { &hf_isis_lsp_checksum,
1930 { "Checksum", "isis.lsp.checksum",FT_UINT16,
1931 BASE_HEX, NULL, 0x0, "", HFILL }},
1933 { &hf_isis_lsp_checksum_bad,
1934 { "Bad Checksum", "isis.lsp.checksum_bad", FT_BOOLEAN, BASE_NONE,
1935 NULL, 0, "Bad IS-IS LSP Checksum", HFILL }},
1937 { &hf_isis_lsp_clv_ipv4_int_addr,
1938 { "IPv4 interface address", "isis.lsp.clv_ipv4_int_addr", FT_IPv4,
1939 BASE_NONE, NULL, 0x0, "", HFILL }},
1941 { &hf_isis_lsp_clv_ipv6_int_addr,
1942 { "IPv6 interface address", "isis.lsp.clv_ipv6_int_addr", FT_IPv6,
1943 BASE_NONE, NULL, 0x0, "", HFILL }},
1945 { &hf_isis_lsp_clv_te_router_id,
1946 { "Traffic Engineering Router ID", "isis.lsp.clv_te_router_id", FT_IPv4,
1947 BASE_NONE, NULL, 0x0, "", HFILL }},
1949 { &hf_isis_lsp_clv_mt,
1950 { "MT-ID ", "isis.lsp.clv_mt",
1951 FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
1954 { "Partition Repair", "isis.lsp.partition_repair", FT_BOOLEAN, 8,
1955 TFS(&supported_string), ISIS_LSP_PARTITION_MASK,
1956 "If set, this router supports the optional Partition Repair function", HFILL }},
1959 { "Attachment", "isis.lsp.att", FT_UINT8, BASE_DEC,
1960 NULL, ISIS_LSP_ATT_MASK,
1963 { &hf_isis_lsp_hippity,
1964 { "Overload bit", "isis.lsp.overload", FT_BOOLEAN, 8,
1965 TFS(&hippity_string), ISIS_LSP_HIPPITY_MASK,
1966 "If set, this router will not be used by any decision process to calculate routes", HFILL }},
1968 { &hf_isis_lsp_is_type,
1969 { "Type of Intermediate System", "isis.lsp.is_type", FT_UINT8, BASE_DEC,
1970 VALS(isis_lsp_istype_vals), ISIS_LSP_IS_TYPE_MASK,
1973 static gint *ett[] = {
1977 &ett_isis_lsp_clv_area_addr,
1978 &ett_isis_lsp_clv_is_neighbors,
1979 &ett_isis_lsp_clv_ext_is_reachability, /* CLV 22 */
1980 &ett_isis_lsp_part_of_clv_ext_is_reachability,
1981 &ett_isis_lsp_subclv_admin_group,
1982 &ett_isis_lsp_subclv_unrsv_bw,
1983 &ett_isis_lsp_clv_unknown,
1984 &ett_isis_lsp_clv_partition_dis,
1985 &ett_isis_lsp_clv_prefix_neighbors,
1986 &ett_isis_lsp_clv_authentication,
1987 &ett_isis_lsp_clv_ip_authentication,
1988 &ett_isis_lsp_clv_nlpid,
1989 &ett_isis_lsp_clv_hostname,
1990 &ett_isis_lsp_clv_ipv4_int_addr,
1991 &ett_isis_lsp_clv_ipv6_int_addr, /* CLV 232 */
1992 &ett_isis_lsp_clv_te_router_id,
1993 &ett_isis_lsp_clv_ip_reachability,
1994 &ett_isis_lsp_clv_ip_reach_subclv,
1995 &ett_isis_lsp_clv_ext_ip_reachability, /* CLV 135 */
1996 &ett_isis_lsp_part_of_clv_ext_ip_reachability,
1997 &ett_isis_lsp_clv_ipv6_reachability, /* CLV 236 */
1998 &ett_isis_lsp_part_of_clv_ipv6_reachability,
1999 &ett_isis_lsp_clv_mt,
2000 &ett_isis_lsp_clv_mt_is,
2001 &ett_isis_lsp_part_of_clv_mt_is,
2002 &ett_isis_lsp_clv_mt_reachable_IPv4_prefx,
2003 &ett_isis_lsp_clv_mt_reachable_IPv6_prefx,
2006 proto_register_field_array(proto_isis, hf, array_length(hf));
2007 proto_register_subtree_array(ett, array_length(ett));