2 * Routines for decoding isis lsp packets and their CLVs
4 * $Id: packet-isis-lsp.c,v 1.44 2003/05/28 22:39:14 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_auth = -1;
74 static gint ett_isis_lsp_clv_ipv4_int_addr = -1;
75 static gint ett_isis_lsp_clv_ipv6_int_addr = -1; /* CLV 232 */
76 static gint ett_isis_lsp_clv_ip_reachability = -1;
77 static gint ett_isis_lsp_clv_ip_reach_subclv = -1;
78 static gint ett_isis_lsp_clv_ext_ip_reachability = -1; /* CLV 135 */
79 static gint ett_isis_lsp_part_of_clv_ext_ip_reachability = -1;
80 static gint ett_isis_lsp_clv_ipv6_reachability = -1; /* CLV 236 */
81 static gint ett_isis_lsp_part_of_clv_ipv6_reachability = -1;
82 static gint ett_isis_lsp_clv_mt = -1;
83 static gint ett_isis_lsp_clv_mt_is = -1;
84 static gint ett_isis_lsp_part_of_clv_mt_is = -1;
85 static gint ett_isis_lsp_clv_mt_reachable_IPv4_prefx = -1; /* CLV 235 */
86 static gint ett_isis_lsp_clv_mt_reachable_IPv6_prefx = -1; /* CLV 237 */
88 static const value_string isis_lsp_istype_vals[] = {
89 { ISIS_LSP_TYPE_UNUSED0, "Unused 0x0 (invalid)"},
90 { ISIS_LSP_TYPE_LEVEL_1, "Level 1"},
91 { ISIS_LSP_TYPE_UNUSED2, "Unused 0x2 (invalid)"},
92 { ISIS_LSP_TYPE_LEVEL_2, "Level 2"},
95 static const true_false_string supported_string = {
100 static const true_false_string hippity_string = {
107 * Predclare dissectors for use in clv dissection.
109 static void dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb,
110 proto_tree *tree, int offset, int id_length, int length);
111 static void dissect_lsp_partition_dis_clv(tvbuff_t *tvb,
112 proto_tree *tree, int offset, int id_length, int length);
113 static void dissect_lsp_mt_is_reachability_clv(tvbuff_t *tvb,
114 proto_tree *tree, int offset, int id_length, int length);
115 static void dissect_lsp_ext_is_reachability_clv(tvbuff_t *tvb,
116 proto_tree *tree, int offset, int id_length, int length);
117 static void dissect_lsp_l2_is_neighbors_clv(tvbuff_t *tvb,
118 proto_tree *tree, int offset, int id_length, int length);
119 static void dissect_lsp_l1_es_neighbors_clv(tvbuff_t *tvb,
120 proto_tree *tree, int offset, int id_length, int length);
121 static void dissect_lsp_l1_is_neighbors_clv(tvbuff_t *tvb,
122 proto_tree *tree, int offset, int id_length, int length);
123 static void dissect_lsp_area_address_clv(tvbuff_t *tvb,
124 proto_tree *tree, int offset, int id_length, int length);
125 static void dissect_lsp_l2_auth_clv(tvbuff_t *tvb,
126 proto_tree *tree, int offset, int id_length, int length);
127 static void dissect_lsp_l1_auth_clv(tvbuff_t *tvb,
128 proto_tree *tree, int offset, int id_length, int length);
129 static void dissect_lsp_ipv6_int_addr_clv(tvbuff_t *tvb,
130 proto_tree *tree, int offset, int id_length, int length);
131 static void dissect_lsp_ip_int_addr_clv(tvbuff_t *tvb,
132 proto_tree *tree, int offset, int id_length, int length);
133 static void dissect_lsp_te_router_id_clv(tvbuff_t *tvb,
134 proto_tree *tree, int offset, int id_length, int length);
135 static void dissect_lsp_hostname_clv(tvbuff_t *tvb,
136 proto_tree *tree, int offset, int id_length, int length);
137 static void dissect_lsp_mt_clv(tvbuff_t *tvb,
138 proto_tree *tree, int offset, int id_length, int length);
139 static void dissect_lsp_nlpid_clv(tvbuff_t *tvb,
140 proto_tree *tree, int offset, int id_length, int length);
141 static void dissect_lsp_ipv6_reachability_clv(tvbuff_t *tvb,
142 proto_tree *tree, int offset, int id_length, int length);
143 static void dissect_lsp_ext_ip_reachability_clv(tvbuff_t *tvb,
144 proto_tree *tree, int offset, int id_length, int length);
145 static void dissect_lsp_ip_reachability_clv(tvbuff_t *tvb,
146 proto_tree *tree, int offset, int id_length, int length);
147 static void dissect_ipreach_subclv(tvbuff_t *tvb,
148 proto_tree *tree, int offset, int clv_code, int clv_len);
149 static void dissect_lsp_mt_reachable_IPv4_prefx_clv(tvbuff_t *tvb,
150 proto_tree *tree, int offset, int id_length, int length);
151 static void dissect_lsp_mt_reachable_IPv6_prefx_clv(tvbuff_t *tvb,
152 proto_tree *tree, int offset, int id_length, int length);
155 static const isis_clv_handle_t clv_l1_lsp_opts[] = {
157 ISIS_CLV_L1_LSP_AREA_ADDRESS,
159 &ett_isis_lsp_clv_area_addr,
160 dissect_lsp_area_address_clv
163 ISIS_CLV_L1_LSP_IS_NEIGHBORS,
165 &ett_isis_lsp_clv_is_neighbors,
166 dissect_lsp_l1_is_neighbors_clv
169 ISIS_CLV_L1_LSP_ES_NEIGHBORS,
171 &ett_isis_lsp_clv_is_neighbors,
172 dissect_lsp_l1_es_neighbors_clv
175 ISIS_CLV_L1_LSP_EXT_IS_REACHABLE,
176 "Extended IS reachability",
177 &ett_isis_lsp_clv_ext_is_reachability,
178 dissect_lsp_ext_is_reachability_clv
181 ISIS_CLV_L1_LSP_IP_INT_REACHABLE,
182 "IP Internal reachability",
183 &ett_isis_lsp_clv_ip_reachability,
184 dissect_lsp_ip_reachability_clv
187 ISIS_CLV_L1_LSP_IP_EXT_REACHABLE,
188 "IP External reachability",
189 &ett_isis_lsp_clv_ip_reachability,
190 dissect_lsp_ip_reachability_clv
193 ISIS_CLV_L1_LSP_EXT_IP_REACHABLE,
194 "Extended IP Reachability",
195 &ett_isis_lsp_clv_ext_ip_reachability,
196 dissect_lsp_ext_ip_reachability_clv
199 ISIS_CLV_L1_LSP_IPv6_REACHABLE,
201 &ett_isis_lsp_clv_ipv6_reachability,
202 dissect_lsp_ipv6_reachability_clv
205 ISIS_CLV_L1_LSP_NLPID,
206 "Protocols supported",
207 &ett_isis_lsp_clv_nlpid,
208 dissect_lsp_nlpid_clv
211 ISIS_CLV_L1_LSP_HOSTNAME,
213 &ett_isis_lsp_clv_hostname,
214 dissect_lsp_hostname_clv
217 ISIS_CLV_L1_LSP_TE_ROUTER_ID,
218 "Traffic Engineering Router ID",
219 &ett_isis_lsp_clv_te_router_id,
220 dissect_lsp_te_router_id_clv
223 ISIS_CLV_L1_LSP_IP_INTERFACE_ADDR,
224 "IP Interface address(es)",
225 &ett_isis_lsp_clv_ipv4_int_addr,
226 dissect_lsp_ip_int_addr_clv
229 ISIS_CLV_L1_LSP_IPv6_INTERFACE_ADDR,
230 "IPv6 Interface address(es)",
231 &ett_isis_lsp_clv_ipv6_int_addr,
232 dissect_lsp_ipv6_int_addr_clv
235 ISIS_CLV_L1_LSP_AUTHENTICATION_NS,
236 "Authentication(non-spec)",
237 &ett_isis_lsp_clv_auth,
238 dissect_lsp_l1_auth_clv
241 ISIS_CLV_L1_LSP_AUTHENTICATION,
243 &ett_isis_lsp_clv_auth,
244 dissect_lsp_l1_auth_clv
249 &ett_isis_lsp_clv_mt,
253 ISIS_CLV_L1_LSP_MT_IS_REACHABLE,
254 "Multi Topology IS Reachability",
255 &ett_isis_lsp_clv_mt_is,
256 dissect_lsp_mt_is_reachability_clv
259 ISIS_CLV_L1_LSP_MT_REACHABLE_IPv4_PREFX,
260 "Multi Topology Reachable IPv4 Prefixes",
261 &ett_isis_lsp_clv_mt_reachable_IPv4_prefx,
262 dissect_lsp_mt_reachable_IPv4_prefx_clv
265 ISIS_CLV_L1_LSP_MT_REACHABLE_IPv6_PREFX,
266 "Multi Topology Reachable IPv6 Prefixes",
267 &ett_isis_lsp_clv_mt_reachable_IPv6_prefx,
268 dissect_lsp_mt_reachable_IPv6_prefx_clv
278 static const isis_clv_handle_t clv_l2_lsp_opts[] = {
280 ISIS_CLV_L1_LSP_AREA_ADDRESS,
282 &ett_isis_lsp_clv_area_addr,
283 dissect_lsp_area_address_clv
286 ISIS_CLV_L2_LSP_IS_NEIGHBORS,
288 &ett_isis_lsp_clv_is_neighbors,
289 dissect_lsp_l2_is_neighbors_clv
292 ISIS_CLV_L2_LSP_EXT_IS_REACHABLE,
293 "Extended IS reachability",
294 &ett_isis_lsp_clv_ext_is_reachability,
295 dissect_lsp_ext_is_reachability_clv
298 ISIS_CLV_L2_LSP_PARTITION_DIS,
299 "Parition Designated Level 2 IS",
300 &ett_isis_lsp_clv_partition_dis,
301 dissect_lsp_partition_dis_clv
304 ISIS_CLV_L2_LSP_PREFIX_NEIGHBORS,
306 &ett_isis_lsp_clv_prefix_neighbors,
307 dissect_lsp_prefix_neighbors_clv
310 ISIS_CLV_L2_LSP_IP_INT_REACHABLE,
311 "IP Internal reachability",
312 &ett_isis_lsp_clv_ip_reachability,
313 dissect_lsp_ip_reachability_clv
316 ISIS_CLV_L2_LSP_IP_EXT_REACHABLE,
317 "IP External reachability",
318 &ett_isis_lsp_clv_ip_reachability,
319 dissect_lsp_ip_reachability_clv
322 ISIS_CLV_L2_LSP_NLPID,
323 "Protocols supported",
324 &ett_isis_lsp_clv_nlpid,
325 dissect_lsp_nlpid_clv
328 ISIS_CLV_L2_LSP_HOSTNAME,
330 &ett_isis_lsp_clv_hostname,
331 dissect_lsp_hostname_clv
334 ISIS_CLV_L2_LSP_TE_ROUTER_ID,
335 "Traffic Engineering Router ID",
336 &ett_isis_lsp_clv_te_router_id,
337 dissect_lsp_te_router_id_clv
340 ISIS_CLV_L2_LSP_EXT_IP_REACHABLE,
341 "Extended IP Reachability",
342 &ett_isis_lsp_clv_ext_ip_reachability,
343 dissect_lsp_ext_ip_reachability_clv
346 ISIS_CLV_L2_LSP_IPv6_REACHABLE,
348 &ett_isis_lsp_clv_ipv6_reachability,
349 dissect_lsp_ipv6_reachability_clv
352 ISIS_CLV_L2_LSP_IP_INTERFACE_ADDR,
353 "IP Interface address(es)",
354 &ett_isis_lsp_clv_ipv4_int_addr,
355 dissect_lsp_ip_int_addr_clv
358 ISIS_CLV_L2_LSP_IPv6_INTERFACE_ADDR,
359 "IPv6 Interface address(es)",
360 &ett_isis_lsp_clv_ipv6_int_addr,
361 dissect_lsp_ipv6_int_addr_clv
364 ISIS_CLV_L2_LSP_AUTHENTICATION_NS,
365 "Authentication(non spec)",
366 &ett_isis_lsp_clv_auth,
367 dissect_lsp_l2_auth_clv
370 ISIS_CLV_L2_LSP_AUTHENTICATION,
372 &ett_isis_lsp_clv_auth,
373 dissect_lsp_l2_auth_clv
378 &ett_isis_lsp_clv_mt,
382 ISIS_CLV_L2_LSP_MT_IS_REACHABLE,
383 "Multi Topology IS Reachability",
384 &ett_isis_lsp_clv_mt_is,
385 dissect_lsp_mt_is_reachability_clv
388 ISIS_CLV_L2_LSP_MT_REACHABLE_IPv4_PREFX,
389 "Multi Topology Reachable IPv4 Prefixes",
390 &ett_isis_lsp_clv_mt_reachable_IPv4_prefx,
391 dissect_lsp_mt_reachable_IPv4_prefx_clv
394 ISIS_CLV_L2_LSP_MT_REACHABLE_IPv6_PREFX,
395 "Multi Topology Reachable IPv6 Prefixes",
396 &ett_isis_lsp_clv_mt_reachable_IPv6_prefx,
397 dissect_lsp_mt_reachable_IPv6_prefx_clv
408 * Name: dissect_lsp_mt_id()
411 * dissect and display the multi-topology ID value
414 * tvbuff_t * : tvbuffer for packet data
415 * proto_tree * : protocol display tree to fill out. CAN'T BE NULL
416 * int : offset into packet data where we are.
419 * void, but we will add to proto tree.
422 dissect_lsp_mt_id(tvbuff_t *tvb, proto_tree *tree, int offset)
427 /* fetch two bytes */
428 mt_block = tvb_get_ntohs(tvb, offset);
430 proto_tree_add_text ( tree, tvb, offset, 1 ,
431 "4 most significant bits reserved, should be set to 0 (%d)", ISIS_LSP_MT_MSHIP_RES(mt_block));
433 mt_id = ISIS_LSP_MT_MSHIP_ID(mt_block);
434 /*mask out the lower 12 bits */
437 strcpy(mt_desc,"'standard' topology");
440 strcpy(mt_desc,"IPv4 In-Band Management purposes");
443 strcpy(mt_desc,"IPv6 routing topology");
446 strcpy(mt_desc,"IPv4 multicast routing topology");
449 strcpy(mt_desc,"IPv6 multicast routing topology");
452 strcpy(mt_desc,((mt_block & 0x0fff) < 3996) ? "Reserved for IETF Consensus" : "Development, Experimental and Proprietary features");
455 proto_tree_add_text ( tree, tvb, offset, 2 ,
456 "%s (%d)", mt_desc, mt_id);
461 * Name: dissect_metric()
464 * Display a metric prefix portion. ISIS has the concept of multple
465 * metric per prefix (default, delay, expense, and error). This
466 * routine assists other dissectors by adding a single one of
467 * these to the display tree..
469 * The 8th(msbit) bit in the metric octet is the "supported" bit. The
470 * "default" support is required, so we support a "force_supported"
471 * flag that tells us that it MUST be zero (zero==supported,
472 * so it really should be a "not supported" in the boolean sense)
473 * and to display a protocol failure accordingly. Notably,
474 * Cisco IOS 12(6) blows this!
475 * The 7th bit must be zero (reserved).
478 * tvbuff_t * : tvbuffer for packet data
479 * proto_tree * : protocol display tree to fill out. May be NULL
480 * int : offset into packet data where we are.
481 * guint8 : value of the metric.
482 * char * : string giving type of the metric.
483 * int : force supported. True is the supported bit MUST be zero.
486 * void, but we will add to proto tree if !NULL.
489 dissect_metric(tvbuff_t *tvb, proto_tree *tree, int offset, guint8 value,
490 char *pstr, int force_supported )
496 s = ISIS_LSP_CLV_METRIC_SUPPORTED(value);
497 proto_tree_add_text(tree, tvb, offset, 1,
498 "%s Metric: %s%s %s%d:%d", pstr,
499 s ? "Not supported" : "Supported",
500 (s && force_supported) ? "(but is required to be)":"",
501 ISIS_LSP_CLV_METRIC_RESERVED(value) ? "(reserved bit != 0)":"",
502 ISIS_LSP_CLV_METRIC_VALUE(value), value );
506 * Name: dissect_lsp_ip_reachability_clv()
509 * Decode an IP reachability CLV. This can be either internal or
510 * external (the clv format does not change and which type we are
511 * displaying is put there by the dispatcher). All of these
512 * are a metric block followed by an IP addr and mask.
515 * tvbuff_t * : tvbuffer for packet data
516 * proto_tree * : proto tree to build on (may be null)
517 * int : current offset into packet data
518 * int : length of IDs in packet.
519 * int : length of this clv
522 * void, will modify proto_tree if not null.
525 dissect_lsp_ip_reachability_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
526 int id_length _U_, int length)
529 proto_tree *ntree = NULL;
530 guint32 src, mask, prefix_len;
532 guint32 bitmasks[33] = {
534 0x00000008, 0x0000000c, 0x0000000e, 0x0000000f,
535 0x000000f8, 0x000000fc, 0x000000fe, 0x000000ff,
536 0x000008ff, 0x00000cff, 0x00000eff, 0x00000fff,
537 0x0000f8ff, 0x0000fcff, 0x0000feff, 0x0000ffff,
538 0x0008ffff, 0x000cffff, 0x000effff, 0x000fffff,
539 0x00f8ffff, 0x00fcffff, 0x00feffff, 0x00ffffff,
540 0x08ffffff, 0x0cffffff, 0x0effffff, 0x0fffffff,
541 0xf8ffffff, 0xfcffffff, 0xfeffffff, 0xffffffff
545 while ( length > 0 ) {
547 isis_dissect_unknown(tvb, tree, offset,
548 "short IP reachability (%d vs 12)", length );
552 * Gotta build a sub-tree for all our pieces
555 tvb_memcpy(tvb, (guint8 *)&src, offset+4, 4);
556 tvb_memcpy(tvb, (guint8 *)&mask, offset+8, 4);
558 /* find out if the mask matches one of 33 possible prefix lengths */
562 while(prefix_len<=33) {
563 if (bitmasks[prefix_len++]==mask) {
569 /* 34 indicates no match -> must be a discontiguous netmask
570 lets dump the mask, otherwise print the prefix_len */
573 ti = proto_tree_add_text ( tree, tvb, offset, 12,
574 "IPv4 prefix: %s mask %s",
575 ip_to_str((guint8*)&src),
576 ip_to_str((guint8*)&mask));
578 ti = proto_tree_add_text ( tree, tvb, offset, 12,
579 "IPv4 prefix: %s/%d",
580 ip_to_str((guint8*)&src),
584 ntree = proto_item_add_subtree(ti,
585 ett_isis_lsp_clv_ip_reachability);
587 proto_tree_add_text (ntree, tvb, offset, 1,
588 "Default Metric: %d, %s, Distribution: %s",
589 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset)),
590 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset)) ? "External" : "Internal",
591 ISIS_LSP_CLV_METRIC_UPDOWN(tvb_get_guint8(tvb, offset)) ? "down" : "up");
594 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+1))) {
595 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: Not supported");
597 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: %d, %s",
598 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+1)),
599 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+1)) ? "External" : "Internal");
602 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+2))) {
603 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: Not supported");
605 proto_tree_add_text (ntree, tvb, offset+2, 1, "Exense Metric: %d, %s",
606 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+2)),
607 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+2)) ? "External" : "Internal");
610 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+3))) {
611 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: Not supported");
613 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: %d, %s",
614 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+3)),
615 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+3)) ? "External" : "Internal");
624 * Name: dissect_ipreach_subclv ()
626 * Description: parses IP reach subTLVs
627 * Called by various IP Reachability dissectors.
630 * tvbuff_t * : tvbuffer for packet data
631 * proto_tree * : protocol display tree to fill out.
632 * int : offset into packet data where we are (beginning of the sub_clv value).
638 dissect_ipreach_subclv(tvbuff_t *tvb, proto_tree *tree, int offset, int clv_code, int clv_len)
643 while (clv_len >= 4) {
644 proto_tree_add_text(tree, tvb, offset, 4,
645 "32-Bit Administrative tag: 0x%08x (=%u)",
646 tvb_get_ntohl(tvb, offset),
647 tvb_get_ntohl(tvb, offset));
653 while (clv_len >= 8) {
654 proto_tree_add_text(tree, tvb, offset, 8,
655 "64-Bit Administrative tag: 0x%08x%08x",
656 tvb_get_ntohl(tvb, offset),
657 tvb_get_ntohl(tvb, offset+4));
664 proto_tree_add_text (tree, tvb, offset, clv_len+2,
665 "Unknown sub-TLV: code %u, length %u",
673 * Name: dissect_lsp_ext_ip_reachability_clv()
675 * Description: Decode an Extended IP Reachability CLV - code 135.
677 * The extended IP reachability TLV is an extended version
678 * of the IP reachability TLVs (codes 128 and 130). It encodes
679 * the metric as a 32-bit unsigned interger and allows to add
682 * CALLED BY TLV 235 DISSECTOR
686 * tvbuff_t * : tvbuffer for packet data
687 * proto_tree * : proto tree to build on (may be null)
688 * int : current offset into packet data
689 * int : length of IDs in packet.
690 * int : length of this clv
693 * void, will modify proto_tree if not null.
696 dissect_lsp_ext_ip_reachability_clv(tvbuff_t *tvb, proto_tree *tree,
697 int offset, int id_length _U_, int length)
699 proto_item *pi = NULL;
700 proto_tree *subtree = NULL;
701 proto_tree *subtree2 = NULL;
703 guint8 bit_length, byte_length;
708 guint8 clv_code, clv_len;
713 memset (prefix, 0, 4);
714 ctrl_info = tvb_get_guint8(tvb, offset+4);
715 bit_length = ctrl_info & 0x3f;
716 byte_length = (bit_length + 7) / 8;
717 if (byte_length > sizeof(prefix)) {
718 isis_dissect_unknown(tvb, tree, offset,
719 "IPv4 prefix has an invalid length: %d bytes", byte_length );
722 tvb_memcpy (tvb, prefix, offset+5, byte_length);
723 metric = tvb_get_ntohl(tvb, offset);
725 if ((ctrl_info & 0x40) != 0)
726 subclvs_len = 1+tvb_get_guint8(tvb, offset+5+byte_length);
728 pi = proto_tree_add_text (tree, tvb, offset, 5+byte_length+subclvs_len,
729 "IPv4 prefix: %s/%d, Metric: %u, Distribution: %s, %ssub-TLVs present",
733 ((ctrl_info & 0x80) == 0) ? "up" : "down",
734 ((ctrl_info & 0x40) == 0) ? "no " : "" );
736 /* open up a new tree per prefix */
737 subtree = proto_item_add_subtree (pi, ett_isis_lsp_part_of_clv_ext_ip_reachability);
739 proto_tree_add_text (subtree, tvb, offset+5, byte_length, "IPv4 prefix: %s/%u",
743 proto_tree_add_text (subtree, tvb, offset, 4, "Metric: %u", metric);
745 proto_tree_add_text (subtree, tvb, offset+4, 1, "Distribution: %s",
746 ((ctrl_info & 0x80) == 0) ? "up" : "down");
748 len = 5 + byte_length;
749 if ((ctrl_info & 0x40) != 0) {
750 subclvs_len = tvb_get_guint8(tvb, offset+len);
751 pi = proto_tree_add_text (subtree, tvb, offset+len, 1, "sub-TLVs present, total length: %u bytes",
753 proto_item_set_len (pi, subclvs_len+1);
754 /* open up a new tree for the subTLVs */
755 subtree2 = proto_item_add_subtree (pi, ett_isis_lsp_clv_ip_reach_subclv);
758 while (i < subclvs_len) {
759 clv_code = tvb_get_guint8(tvb, offset+len+1); /* skip the total subtlv len indicator */
760 clv_len = tvb_get_guint8(tvb, offset+len+2);
763 * we pass on now the raw data to the ipreach_subtlv dissector
764 * therefore we need to skip 3 bytes
765 * (total subtlv len, subtlv type, subtlv len)
767 dissect_ipreach_subclv(tvb, subtree2, offset+len+3, clv_code, clv_len);
770 len += 1 + subclvs_len;
772 proto_tree_add_text (subtree, tvb, offset+4, 1, "no sub-TLVs present");
773 proto_item_set_len (pi, len);
782 * Name: dissect_lsp_ipv6_reachability_clv()
784 * Description: Decode an IPv6 reachability CLV - code 236.
786 * CALLED BY TLV 237 DISSECTOR
789 * tvbuff_t * : tvbuffer for packet data
790 * proto_tree * : proto tree to build on (may be null)
791 * int : current offset into packet data
792 * int : length of IDs in packet.
793 * int : length of this clv
796 * void, will modify proto_tree if not null.
799 dissect_lsp_ipv6_reachability_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
800 int id_length _U_, int length)
803 proto_tree *subtree = NULL;
804 proto_tree *subtree2 = NULL;
806 guint8 bit_length, byte_length;
807 struct e_in6_addr prefix;
811 guint8 clv_code, clv_len;
816 memset (prefix.s6_addr, 0, 16);
817 ctrl_info = tvb_get_guint8(tvb, offset+4);
818 bit_length = tvb_get_guint8(tvb, offset+5);
819 byte_length = (bit_length + 7) / 8;
820 if (byte_length > sizeof(prefix)) {
821 isis_dissect_unknown(tvb, tree, offset,
822 "IPv6 prefix has an invalid length: %d bytes", byte_length );
825 tvb_memcpy (tvb, prefix.s6_addr, offset+6, byte_length);
826 metric = tvb_get_ntohl(tvb, offset);
828 if ((ctrl_info & 0x20) != 0)
829 subclvs_len = 1+tvb_get_guint8(tvb, offset+6+byte_length);
831 pi = proto_tree_add_text (tree, tvb, offset, 6+byte_length+subclvs_len,
832 "IPv6 prefix: %s/%u, Metric: %u, Distribution: %s, %s, %ssub-TLVs present",
833 ip6_to_str (&prefix),
836 ((ctrl_info & 0x80) == 0) ? "up" : "down",
837 ((ctrl_info & 0x40) == 0) ? "internal" : "external",
838 ((ctrl_info & 0x20) == 0) ? "no " : "" );
840 subtree = proto_item_add_subtree (pi, ett_isis_lsp_part_of_clv_ipv6_reachability);
842 proto_tree_add_text (subtree, tvb, offset+6, byte_length, "IPv6 prefix: %s/%u",
843 ip6_to_str (&prefix),
846 proto_tree_add_text (subtree, tvb, offset, 4,
847 "Metric: %u", metric);
849 proto_tree_add_text (subtree, tvb, offset+4, 1,
850 "Distribution: %s, %s",
851 ((ctrl_info & 0x80) == 0) ? "up" : "down",
852 ((ctrl_info & 0x40) == 0) ? "internal" : "external" );
854 if ((ctrl_info & 0x1f) != 0) {
855 proto_tree_add_text (subtree, tvb, offset+4, 1,
856 "Reserved bits: 0x%x",
857 (ctrl_info & 0x1f) );
860 len = 6 + byte_length;
861 if ((ctrl_info & 0x20) != 0) {
862 subclvs_len = tvb_get_guint8(tvb, offset+len);
863 pi = proto_tree_add_text (subtree, tvb, offset+len, 1, "sub-TLVs present, total length: %u bytes",
865 proto_item_set_len (pi, subclvs_len+1);
866 /* open up a new tree for the subTLVs */
867 subtree2 = proto_item_add_subtree (pi, ett_isis_lsp_clv_ip_reach_subclv);
870 while (i < subclvs_len) {
871 clv_code = tvb_get_guint8(tvb, offset+len+1); /* skip the total subtlv len indicator */
872 clv_len = tvb_get_guint8(tvb, offset+len+2);
873 dissect_ipreach_subclv(tvb, subtree2, offset+len+3, clv_code, clv_len);
876 len += 1 + subclvs_len;
878 proto_tree_add_text (subtree, tvb, offset+4, 1, "no sub-TLVs present");
879 proto_item_set_len (pi, len);
887 * Name: dissect_lsp_nlpid_clv()
890 * Decode for a lsp packets NLPID clv. Calls into the
894 * tvbuff_t * : tvbuffer for packet data
895 * proto_tree * : proto tree to build on (may be null)
896 * int : current offset into packet data
897 * int : length of IDs in packet.
898 * int : length of this clv
901 * void, will modify proto_tree if not null.
904 dissect_lsp_nlpid_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
905 int id_length _U_, int length)
907 isis_dissect_nlpid_clv(tvb, tree, offset, length);
911 * Name: dissect_lsp_mt_clv()
913 * Description: - code 229
914 * Decode for a lsp packets Multi Topology clv. Calls into the
918 * tvbuff_t * : tvbuffer for packet data
919 * proto_tree * : proto tree to build on (may be null)
920 * int : current offset into packet data
921 * guint : length of this clv
922 * int : length of IDs in packet.
925 * void, will modify proto_tree if not null.
928 dissect_lsp_mt_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
929 int id_length _U_, int length)
931 isis_dissect_mt_clv(tvb, tree, offset, length, hf_isis_lsp_clv_mt );
935 * Name: dissect_lsp_hostname_clv()
938 * Decode for a lsp packets hostname clv. Calls into the
942 * tvbuff_t * : tvbuffer for packet data
943 * proto_tree * : proto tree to build on (may be null)
944 * int : current offset into packet data
945 * int : length of IDs in packet.
946 * int : length of this clv
949 * void, will modify proto_tree if not null.
952 dissect_lsp_hostname_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
953 int id_length _U_, int length)
955 isis_dissect_hostname_clv(tvb, tree, offset, length);
960 * Name: dissect_lsp_te_router_id_clv()
963 * Decode for a lsp packets Traffic Engineering ID clv. Calls into the
967 * tvbuff_t * : tvbuffer for packet data
968 * proto_tree * : proto tree to build on (may be null)
969 * int : current offset into packet data
970 * int : length of IDs in packet.
971 * int : length of this clv
974 * void, will modify proto_tree if not null.
977 dissect_lsp_te_router_id_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
978 int id_length _U_, int length)
980 isis_dissect_te_router_id_clv(tvb, tree, offset, length,
981 hf_isis_lsp_clv_te_router_id );
986 * Name: dissect_lsp_ip_int_addr_clv()
989 * Decode for a lsp packets ip interface addr clv. Calls into the
993 * tvbuff_t * : tvbuffer for packet data
994 * proto_tree * : proto tree to build on (may be null)
995 * int : current offset into packet data
996 * int : length of IDs in packet.
997 * int : length of this clv
1000 * void, will modify proto_tree if not null.
1003 dissect_lsp_ip_int_addr_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1004 int id_length _U_, int length)
1006 isis_dissect_ip_int_clv(tvb, tree, offset, length,
1007 hf_isis_lsp_clv_ipv4_int_addr );
1011 * Name: dissect_lsp_ipv6_int_addr_clv()
1013 * Description: Decode an IPv6 interface addr CLV - code 232.
1015 * Calls into the clv common one.
1018 * tvbuff_t * : tvbuffer for packet data
1019 * proto_tree * : proto tree to build on (may be null)
1020 * int : current offset into packet data
1021 * int : length of IDs in packet.
1022 * int : length of this clv
1025 * void, will modify proto_tree if not null.
1028 dissect_lsp_ipv6_int_addr_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1029 int id_length _U_, int length)
1031 isis_dissect_ipv6_int_clv(tvb, tree, offset, length,
1032 hf_isis_lsp_clv_ipv6_int_addr );
1036 * Name: dissect_lsp_L1_auth_clv()
1039 * Decode for a lsp packets authenticaion clv. Calls into the
1040 * clv common one. An auth inside a L1 LSP is a per area password
1043 * tvbuff_t * : tvbuffer for packet data
1044 * proto_tree * : proto tree to build on (may be null)
1045 * int : current offset into packet data
1046 * int : length of IDs in packet.
1047 * int : length of this clv
1050 * void, will modify proto_tree if not null.
1053 dissect_lsp_l1_auth_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1054 int id_length _U_, int length)
1056 isis_dissect_authentication_clv(tvb, tree, offset, length,
1057 "Per area authentication" );
1061 * Name: dissect_lsp_L2_auth_clv()
1064 * Decode for a lsp packets authenticaion clv. Calls into the
1065 * clv common one. An auth inside a L2 LSP is a per domain password
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_l2_auth_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1079 int id_length _U_, int length)
1081 isis_dissect_authentication_clv(tvb, tree, offset, length,
1082 "Per domain authentication" );
1086 * Name: dissect_lsp_area_address_clv()
1089 * Decode for a lsp packet's area address clv. Call into clv common
1093 * tvbuff_t * : tvbuffer for packet data
1094 * proto_tree * : protocol display tree to fill out. May be NULL
1095 * int : offset into packet data where we are.
1096 * int : length of IDs in packet.
1097 * int : length of clv we are decoding
1100 * void, but we will add to proto tree if !NULL.
1103 dissect_lsp_area_address_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1104 int id_length _U_, int length)
1106 isis_dissect_area_address_clv(tvb, tree, offset, length);
1110 * Name: dissect_lsp_eis_neighbors_clv_inner()
1113 * Real work horse for showing neighbors. This means we decode the
1114 * first octet as either virtual/!virtual (if show_virtual param is
1115 * set), or as a must == 0 reserved value.
1117 * Once past that, we decode n neighbor elements. Each neighbor
1118 * is comprised of a metric block (is dissect_metric) and the
1122 * tvbuff_t * : tvbuffer for packet data
1123 * proto_tree * : protocol display tree to fill out. May be NULL
1124 * int : offset into packet data where we are.
1125 * int : length of IDs in packet.
1126 * int : length of clv we are decoding
1127 * int : set to decode first octet as virtual vs reserved == 0
1128 * int : set to indicate EIS instead of IS (6 octet per addr instead of 7)
1131 * void, but we will add to proto tree if !NULL.
1134 dissect_lsp_eis_neighbors_clv_inner(tvbuff_t *tvb, proto_tree *tree,
1135 int offset, int length, int id_length, int show_virtual, int is_eis)
1138 proto_tree *ntree = NULL;
1142 id_length++; /* IDs are one octet longer in IS neighbours */
1144 if ( show_virtual ) {
1145 /* virtual path flag */
1146 proto_tree_add_text ( tree, tvb, offset, 1,
1147 tvb_get_guint8(tvb, offset) ? "IsVirtual" : "IsNotVirtual" );
1149 proto_tree_add_text ( tree, tvb, offset, 1,
1150 "Reserved value 0x%02x, must == 0",
1151 tvb_get_guint8(tvb, offset) );
1157 tlen = 4 + id_length;
1159 while ( length > 0 ) {
1161 isis_dissect_unknown(tvb, tree, offset,
1162 "short E/IS reachability (%d vs %d)", length,
1167 * Gotta build a sub-tree for all our pieces
1171 ti = proto_tree_add_text(tree, tvb, offset, tlen,
1173 print_system_id( tvb_get_ptr(tvb, offset+4, id_length), id_length ) );
1175 ti = proto_tree_add_text(tree, tvb, offset, tlen,
1177 print_system_id(tvb_get_ptr(tvb, offset+4, id_length), id_length ) );
1179 ntree = proto_item_add_subtree(ti,
1180 ett_isis_lsp_clv_is_neighbors);
1184 proto_tree_add_text (ntree, tvb, offset, 1,
1185 "Default Metric: %d, %s",
1186 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset)),
1187 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset)) ? "External" : "Internal");
1189 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+1))) {
1190 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: Not supported");
1192 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: %d, %s",
1193 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+1)),
1194 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+1)) ? "External" : "Internal");
1198 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+2))) {
1199 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: Not supported");
1201 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: %d, %s",
1202 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+2)),
1203 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+2)) ? "External" : "Internal");
1206 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+3))) {
1207 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: Not supported");
1209 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: %d, %s",
1210 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+3)),
1211 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+3)) ? "External" : "Internal");
1221 * Name: dissect_lsp_l1_is_neighbors_clv()
1224 * Dispatch a l1 intermediate system neighbor by calling
1225 * the inner function with show virtual set to TRUE and is es set to FALSE.
1228 * tvbuff_t * : tvbuffer for packet data
1229 * proto_tree * : protocol display tree to fill out. May be NULL
1230 * int : offset into packet data where we are.
1231 * int : length of IDs in packet.
1232 * int : length of clv we are decoding
1235 * void, but we will add to proto tree if !NULL.
1238 dissect_lsp_l1_is_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1239 int id_length, int length)
1241 dissect_lsp_eis_neighbors_clv_inner(tvb, tree, offset,
1242 length, id_length, TRUE, FALSE);
1246 * Name: dissect_lsp_l1_es_neighbors_clv()
1249 * Dispatch a l1 end or intermediate system neighbor by calling
1250 * the inner function with show virtual set to TRUE and es set to TRUE.
1253 * tvbuff_t * : tvbuffer for packet data
1254 * proto_tree * : protocol display tree to fill out. May be NULL
1255 * int : offset into packet data where we are.
1256 * int : length of IDs in packet.
1257 * int : length of clv we are decoding
1260 * void, but we will add to proto tree if !NULL.
1263 dissect_lsp_l1_es_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1264 int id_length, int length)
1266 dissect_lsp_eis_neighbors_clv_inner(tvb, tree, offset,
1267 length, id_length, TRUE, TRUE);
1271 * Name: dissect_lsp_l2_is_neighbors_clv()
1274 * Dispatch a l2 intermediate system neighbor by calling
1275 * the inner function with show virtual set to FALSE, and is es set
1279 * tvbuff_t * : tvbuffer for packet data
1280 * proto_tree * : protocol display tree to fill out. May be NULL
1281 * int : offset into packet data where we are.
1282 * int : length of IDs in packet.
1283 * int : length of clv we are decoding
1286 * void, but we will add to proto tree if !NULL.
1289 dissect_lsp_l2_is_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1290 int id_length, int length)
1292 dissect_lsp_eis_neighbors_clv_inner(tvb, tree, offset,
1293 length, id_length, FALSE, FALSE);
1298 * Name: dissect_subclv_admin_group ()
1300 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1302 * This function is called by dissect_lsp_ext_is_reachability_clv()
1303 * for dissect the administrive group sub-CLV (code 3).
1306 * tvbuff_t * : tvbuffer for packet data
1307 * proto_tree * : protocol display tree to fill out.
1308 * int : offset into packet data where we are (beginning of the sub_clv value).
1314 dissect_subclv_admin_group (tvbuff_t *tvb, proto_tree *tree, int offset) {
1321 ti = proto_tree_add_text(tree, tvb, offset-2, 6, "Administrative group(s):");
1322 ntree = proto_item_add_subtree (ti, ett_isis_lsp_subclv_admin_group);
1324 clv_value = tvb_get_ntohl(tvb, offset);
1326 for (i = 0 ; i < 32 ; i++) {
1327 if ( (clv_value & mask) != 0 ) {
1328 proto_tree_add_text (ntree, tvb, offset, 4, "group %d", i);
1335 * Name: dissect_subclv_max_bw ()
1337 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1339 * This function is called by dissect_lsp_ext_is_reachability_clv()
1340 * for dissect the maximum link bandwidth sub-CLV (code 9).
1343 * tvbuff_t * : tvbuffer for packet data
1344 * proto_tree * : protocol display tree to fill out.
1345 * int : offset into packet data where we are (beginning of the sub_clv value).
1351 dissect_subclv_max_bw(tvbuff_t *tvb, proto_tree *tree, int offset)
1355 bw = tvb_get_ntohieee_float(tvb, offset);
1356 proto_tree_add_text (tree, tvb, offset-2, 6,
1357 "Maximum link bandwidth : %.2f Mbps", bw*8/1000000 );
1361 * Name: dissect_subclv_rsv_bw ()
1363 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1365 * This function is called by dissect_lsp_ext_is_reachability_clv()
1366 * for dissect the reservable link bandwidth sub-CLV (code 10).
1369 * tvbuff_t * : tvbuffer for packet data
1370 * proto_tree * : protocol display tree to fill out.
1371 * int : offset into packet data where we are (beginning of the sub_clv value).
1377 dissect_subclv_rsv_bw(tvbuff_t *tvb, proto_tree *tree, int offset)
1381 bw = tvb_get_ntohieee_float(tvb, offset);
1382 proto_tree_add_text (tree, tvb, offset-2, 6,
1383 "Reservable link bandwidth: %.2f Mbps", bw*8/1000000 );
1387 * Name: dissect_subclv_unrsv_bw ()
1389 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1391 * This function is called by dissect_lsp_ext_is_reachability_clv()
1392 * for dissect the unreserved bandwidth sub-CLV (code 11).
1395 * tvbuff_t * : tvbuffer for packet data
1396 * proto_tree * : protocol display tree to fill out.
1397 * int : offset into packet data where we are (beginning of the sub_clv value).
1403 dissect_subclv_unrsv_bw(tvbuff_t *tvb, proto_tree *tree, int offset)
1410 ti = proto_tree_add_text (tree, tvb, offset-2, 34, "Unreserved bandwidth:");
1411 ntree = proto_item_add_subtree (ti, ett_isis_lsp_subclv_unrsv_bw);
1413 for (i = 0 ; i < 8 ; i++) {
1414 bw = tvb_get_ntohieee_float(tvb, offset+4*i);
1415 proto_tree_add_text (ntree, tvb, offset+4*i, 4,
1416 "priority level %d: %.2f Mbps", i, bw*8/1000000 );
1421 * Name: dissect_lsp_ext_is_reachability_clv()
1423 * Description: Decode a Extended IS Reachability CLV - code 22
1425 * The extended IS reachability TLV is an extended version
1426 * of the IS reachability TLV (code 2). It encodes the metric
1427 * as a 24-bit unsigned interger and allows to add sub-CLV(s).
1429 * CALLED BY TLV 222 DISSECTOR
1432 * tvbuff_t * : tvbuffer for packet data
1433 * proto_tree * : protocol display tree to fill out. May be NULL
1434 * int : offset into packet data where we are.
1435 * int : length of IDs in packet.
1436 * int : length of clv we are decoding
1439 * void, but we will add to proto tree if !NULL.
1442 dissect_lsp_ext_is_reachability_clv(tvbuff_t *tvb, proto_tree *tree,
1443 int offset, int id_length _U_, int length)
1446 proto_tree *ntree = NULL;
1449 guint8 clv_code, clv_len;
1453 while (length > 0) {
1454 ti = proto_tree_add_text (tree, tvb, offset, -1,
1456 print_system_id (tvb_get_ptr(tvb, offset, 7), 7) );
1457 ntree = proto_item_add_subtree (ti,
1458 ett_isis_lsp_part_of_clv_ext_is_reachability );
1460 proto_tree_add_text (ntree, tvb, offset+7, 3,
1461 "Metric: %d", tvb_get_ntoh24(tvb, offset+7) );
1463 subclvs_len = tvb_get_guint8(tvb, offset+10);
1464 if (subclvs_len == 0) {
1465 proto_tree_add_text (ntree, tvb, offset+10, 1, "no sub-TLVs present");
1469 while (i < subclvs_len) {
1470 clv_code = tvb_get_guint8(tvb, offset+11+i);
1471 clv_len = tvb_get_guint8(tvb, offset+12+i);
1474 dissect_subclv_admin_group(tvb, ntree, offset+13+i);
1477 proto_tree_add_text (ntree, tvb, offset+11+i, 6,
1478 "IPv4 interface address: %s", ip_to_str (tvb_get_ptr(tvb, offset+13+i, 4)) );
1481 proto_tree_add_text (ntree, tvb, offset+11+i, 6,
1482 "IPv4 neighbor address: %s", ip_to_str (tvb_get_ptr(tvb, offset+13+i, 4)) );
1485 dissect_subclv_max_bw (tvb, ntree, offset+13+i);
1488 dissect_subclv_rsv_bw (tvb, ntree, offset+13+i);
1491 dissect_subclv_unrsv_bw (tvb, ntree, offset+13+i);
1494 proto_tree_add_text (ntree, tvb, offset+11+i, 5,
1495 "Traffic engineering default metric: %d",
1496 tvb_get_ntoh24(tvb, offset+13+i) );
1503 proto_tree_add_text (ntree, tvb, offset+11+i, clv_len+2,
1504 "Unknown Cisco specific extensions: code %d, length %d",
1505 clv_code, clv_len );
1508 proto_tree_add_text (ntree, tvb, offset+11+i, clv_len+2,
1509 "Unknown sub-CLV: code %d, length %d", clv_code, clv_len );
1516 len = 11 + subclvs_len;
1517 proto_item_set_len (ti, len);
1524 * Name: dissect_lsp_mt_reachable_IPv4_prefx_clv()
1526 * Description: Decode Multi-Topology IPv4 Prefixes - code 235
1530 * tvbuff_t * : tvbuffer for packet data
1531 * proto_tree * : protocol display tree to fill out. May be NULL
1532 * int : offset into packet data where we are.
1533 * int : length of IDs in packet.
1534 * int : length of clv we are decoding
1537 * void, but we will add to proto tree if !NULL.
1540 dissect_lsp_mt_reachable_IPv4_prefx_clv(tvbuff_t *tvb,
1541 proto_tree *tree, int offset, int id_length _U_, int length)
1545 isis_dissect_unknown(tvb, tree, offset,
1546 "short lsp multi-topology reachable IPv4 prefixes(%d vs %d)", length,
1550 dissect_lsp_mt_id(tvb, tree, offset);
1551 dissect_lsp_ext_ip_reachability_clv(tvb, tree, offset+2, 0, length-2);
1555 * Name: dissect_lsp_mt_reachable_IPv6_prefx_clv()
1557 * Description: Decode Multi-Topology IPv6 Prefixes - code 237
1561 * tvbuff_t * : tvbuffer for packet data
1562 * proto_tree * : protocol display tree to fill out. May be NULL
1563 * int : offset into packet data where we are.
1564 * int : length of IDs in packet.
1565 * int : length of clv we are decoding
1568 * void, but we will add to proto tree if !NULL.
1571 dissect_lsp_mt_reachable_IPv6_prefx_clv(tvbuff_t *tvb,
1572 proto_tree *tree, int offset, int id_length _U_, int length)
1576 isis_dissect_unknown(tvb, tree, offset,
1577 "short lsp multi-topology reachable IPv6 prefixes(%d vs %d)", length,
1581 dissect_lsp_mt_id(tvb, tree, offset);
1582 dissect_lsp_ipv6_reachability_clv(tvb, tree, offset+2, 0, length-2);
1587 * Name: dissect_lsp_mt_is_reachability_clv()
1589 * Description: Decode Multi-Topology Intermediate Systems - code 222
1593 * tvbuff_t * : tvbuffer for packet data
1594 * proto_tree * : protocol display tree to fill out. May be NULL
1595 * int : offset into packet data where we are.
1597 * int : length of clv we are decoding
1600 * void, but we will add to proto tree if !NULL.
1604 dissect_lsp_mt_is_reachability_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1605 int id_length _U_, int length)
1609 isis_dissect_unknown(tvb, tree, offset,
1610 "short lsp reachability(%d vs %d)", length,
1616 * the MT ID value dissection is used in other LSPs so we push it
1619 dissect_lsp_mt_id(tvb, tree, offset);
1621 * fix here. No need to parse TLV 22 (with bugs) while it is
1622 * already done correctly!!
1624 dissect_lsp_ext_is_reachability_clv(tvb, tree, offset+2, 0, length-2);
1628 * Name: dissect_lsp_partition_dis_clv()
1631 * This CLV is used to indicate which system is the designated
1632 * IS for partition repair. This means just putting out the
1633 * "id_length"-octet IS.
1636 * tvbuff_t * : tvbuffer for packet data
1637 * proto_tree * : protocol display tree to fill out. May be NULL
1638 * int : offset into packet data where we are.
1639 * int : length of IDs in packet.
1640 * int : length of clv we are decoding
1643 * void, but we will add to proto tree if !NULL.
1646 dissect_lsp_partition_dis_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1647 int id_length, int length)
1649 if ( length < id_length ) {
1650 isis_dissect_unknown(tvb, tree, offset,
1651 "short lsp partition DIS(%d vs %d)", length,
1656 * Gotta build a sub-tree for all our pieces
1659 proto_tree_add_text ( tree, tvb, offset, id_length,
1660 "Partition designated L2 IS: %s",
1661 print_system_id( tvb_get_ptr(tvb, offset, id_length), id_length ) );
1663 length -= id_length;
1664 offset += id_length;
1666 isis_dissect_unknown(tvb, tree, offset,
1667 "Long lsp partition DIS, %d left over", length );
1673 * Name: dissect_lsp_prefix_neighbors_clv()
1676 * The prefix CLV describes what other (OSI) networks we can reach
1677 * and what their cost is. It is built from a metric block
1678 * (see dissect_metric) followed by n addresses.
1681 * tvbuff_t * : tvbuffer for packet data
1682 * proto_tree * : protocol display tree to fill out. May be NULL
1683 * int : offset into packet data where we are.
1684 * int : length of IDs in packet.
1685 * int : length of clv we are decoding
1688 * void, but we will add to proto tree if !NULL.
1691 dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1692 int id_length _U_, int length)
1698 isis_dissect_unknown(tvb, tree, offset,
1699 "Short lsp prefix neighbors (%d vs 4)", length );
1703 dissect_metric (tvb, tree, offset,
1704 tvb_get_guint8(tvb, offset), "Default", TRUE );
1705 dissect_metric (tvb, tree, offset+1,
1706 tvb_get_guint8(tvb, offset+1), "Delay", FALSE );
1707 dissect_metric (tvb, tree, offset+2,
1708 tvb_get_guint8(tvb, offset+2), "Expense", FALSE );
1709 dissect_metric (tvb, tree, offset+3,
1710 tvb_get_guint8(tvb, offset+3), "Error", FALSE );
1714 while ( length > 0 ) {
1715 mylen = tvb_get_guint8(tvb, offset);
1718 isis_dissect_unknown(tvb, tree, offset,
1719 "Zero payload space after length in prefix neighbor" );
1722 if ( mylen > length) {
1723 isis_dissect_unknown(tvb, tree, offset,
1724 "Interal length of prefix neighbor too long (%d vs %d)",
1730 * Lets turn the area address into "standard" 0000.0000.etc
1733 sbuf = print_area( tvb_get_ptr(tvb, offset+1, mylen), mylen );
1734 /* and spit it out */
1736 proto_tree_add_text ( tree, tvb, offset, mylen + 1,
1737 "Area address (%d): %s", mylen, sbuf );
1739 offset += mylen + 1;
1740 length -= mylen; /* length already adjusted for len fld*/
1745 * Name: isis_dissect_isis_lsp()
1748 * Print out the LSP part of the main header and then call the CLV
1749 * de-mangler with the right list of valid CLVs.
1752 * tvbuff_t * : tvbuffer for packet data
1753 * proto_tree * : protocol display tree to add to. May be NULL.
1754 * int offset : our offset into packet data.
1755 * int : LSP type, a la packet-isis.h ISIS_TYPE_* values
1756 * int : header length of packet.
1757 * int : length of IDs in packet.
1760 * void, but we will add to proto tree if !NULL.
1763 isis_dissect_isis_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
1764 int lsp_type, int header_length, int id_length)
1766 proto_item *ti, *to, *ta;
1767 proto_tree *lsp_tree = NULL, *info_tree, *att_tree;
1768 guint16 pdu_length, checksum, cacl_checksum=0;
1769 guint8 lsp_info, lsp_att;
1770 int len, offset_checksum;
1773 ti = proto_tree_add_text(tree, tvb, offset, -1,
1775 lsp_tree = proto_item_add_subtree(ti, ett_isis_lsp);
1778 pdu_length = tvb_get_ntohs(tvb, offset);
1780 proto_tree_add_uint(lsp_tree, hf_isis_lsp_pdu_length, tvb,
1781 offset, 2, pdu_length);
1786 proto_tree_add_text(lsp_tree, tvb, offset, 2,
1787 "Remaining Lifetime: %us",
1788 tvb_get_ntohs(tvb, offset));
1791 offset_checksum = offset;
1794 proto_tree_add_text(lsp_tree, tvb, offset, id_length + 2,
1796 print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) );
1799 if (check_col(pinfo->cinfo, COL_INFO)) {
1800 col_append_fstr(pinfo->cinfo, COL_INFO, ", LSP-ID: %s",
1801 print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) );
1803 offset += id_length + 2;
1806 proto_tree_add_uint(lsp_tree, hf_isis_lsp_sequence_number, tvb,
1808 tvb_get_ntohl(tvb, offset));
1810 if (check_col(pinfo->cinfo, COL_INFO)) {
1811 col_append_fstr(pinfo->cinfo, COL_INFO, ", Sequence: 0x%08x, Lifetime: %5us",
1812 tvb_get_ntohl(tvb, offset),
1813 tvb_get_ntohs(tvb, offset - (id_length+2+2)));
1818 checksum = tvb_get_ntohs(tvb, offset);
1819 switch (check_and_get_checksum(tvb, offset_checksum, pdu_length-12, checksum, offset, &cacl_checksum))
1823 proto_tree_add_uint_format(lsp_tree, hf_isis_lsp_checksum, tvb, offset, 2, checksum,
1824 "Checksum: 0x%04x (unused)", checksum);
1827 isis_dissect_unknown(tvb, tree, offset,
1828 "packet length %d went beyond packet",
1829 tvb_length_remaining(tvb, offset_checksum));
1832 proto_tree_add_uint_format(lsp_tree, hf_isis_lsp_checksum, tvb, offset, 2, checksum,
1833 "Checksum: 0x%04x (incorrect, should be 0x%04x)",
1834 checksum, cacl_checksum);
1835 proto_tree_add_boolean_hidden(lsp_tree, hf_isis_lsp_checksum_bad,
1836 tvb, offset, 2, TRUE);
1839 proto_tree_add_uint_format(lsp_tree, hf_isis_lsp_checksum, tvb, offset, 2, checksum,
1840 "Checksum: 0x%04x (correct)", checksum);
1841 proto_tree_add_boolean_hidden(lsp_tree, hf_isis_lsp_checksum_bad,
1842 tvb, offset, 2, FALSE);
1845 g_message("'check_and_get_checksum' returned an invalid value");
1852 * P | ATT | HIPPITY | IS TYPE description.
1854 lsp_info = tvb_get_guint8(tvb, offset);
1855 to = proto_tree_add_text(lsp_tree, tvb, offset, 1,
1856 "Type block(0x%02x): Partition Repair:%d, Attached bits:%d, Overload bit:%d, IS type:%d",
1858 ISIS_LSP_PARTITION(lsp_info),
1859 ISIS_LSP_ATT(lsp_info),
1860 ISIS_LSP_HIPPITY(lsp_info),
1861 ISIS_LSP_IS_TYPE(lsp_info)
1864 info_tree = proto_item_add_subtree(to, ett_isis_lsp_info);
1865 proto_tree_add_boolean(info_tree, hf_isis_lsp_p, tvb, offset, 1, lsp_info);
1866 ta = proto_tree_add_uint(info_tree, hf_isis_lsp_att, tvb, offset, 1, lsp_info);
1867 att_tree = proto_item_add_subtree(ta, ett_isis_lsp_att);
1868 lsp_att = ISIS_LSP_ATT(lsp_info);
1869 proto_tree_add_text(att_tree, tvb, offset, 1,
1870 "%d... = Default metric: %s", ISIS_LSP_ATT_DEFAULT(lsp_att), ISIS_LSP_ATT_DEFAULT(lsp_att) ? "Set" : "Unset");
1871 proto_tree_add_text(att_tree, tvb, offset, 1,
1872 ".%d.. = Delay metric: %s", ISIS_LSP_ATT_DELAY(lsp_att), ISIS_LSP_ATT_DELAY(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 = Error metric: %s", ISIS_LSP_ATT_ERROR(lsp_att), ISIS_LSP_ATT_ERROR(lsp_att) ? "Set" : "Unset");
1877 proto_tree_add_boolean(info_tree, hf_isis_lsp_hippity, tvb, offset, 1, lsp_info);
1878 proto_tree_add_uint(info_tree, hf_isis_lsp_is_type, tvb, offset, 1, lsp_info);
1882 len = pdu_length - header_length;
1884 isis_dissect_unknown(tvb, tree, offset,
1885 "packet header length %d went beyond packet",
1890 * Now, we need to decode our CLVs. We need to pass in
1891 * our list of valid ones!
1893 if (lsp_type == ISIS_TYPE_L1_LSP){
1894 isis_dissect_clvs(tvb, lsp_tree, offset,
1895 clv_l1_lsp_opts, len, id_length,
1896 ett_isis_lsp_clv_unknown );
1898 isis_dissect_clvs(tvb, lsp_tree, offset,
1899 clv_l2_lsp_opts, len, id_length,
1900 ett_isis_lsp_clv_unknown );
1904 * Name: isis_register_lsp()
1907 * Register our protocol sub-sets with protocol manager.
1910 * int : protocol index for the ISIS protocol
1916 isis_register_lsp(int proto_isis) {
1917 static hf_register_info hf[] = {
1918 { &hf_isis_lsp_pdu_length,
1919 { "PDU length", "isis.lsp.pdu_length", FT_UINT16,
1920 BASE_DEC, NULL, 0x0, "", HFILL }},
1922 { &hf_isis_lsp_remaining_life,
1923 { "Remaining lifetime", "isis.lsp.remaining_life", FT_UINT16,
1924 BASE_DEC, NULL, 0x0, "", HFILL }},
1926 { &hf_isis_lsp_sequence_number,
1927 { "Sequence number", "isis.lsp.sequence_number",
1928 FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1930 { &hf_isis_lsp_checksum,
1931 { "Checksum", "isis.lsp.checksum",FT_UINT16,
1932 BASE_HEX, NULL, 0x0, "", HFILL }},
1934 { &hf_isis_lsp_checksum_bad,
1935 { "Bad Checksum", "isis.lsp.checksum_bad", FT_BOOLEAN, BASE_NONE,
1936 NULL, 0, "Bad IS-IS LSP Checksum", HFILL }},
1938 { &hf_isis_lsp_clv_ipv4_int_addr,
1939 { "IPv4 interface address", "isis.lsp.clv_ipv4_int_addr", FT_IPv4,
1940 BASE_NONE, NULL, 0x0, "", HFILL }},
1942 { &hf_isis_lsp_clv_ipv6_int_addr,
1943 { "IPv6 interface address", "isis.lsp.clv_ipv6_int_addr", FT_IPv6,
1944 BASE_NONE, NULL, 0x0, "", HFILL }},
1946 { &hf_isis_lsp_clv_te_router_id,
1947 { "Traffic Engineering Router ID", "isis.lsp.clv_te_router_id", FT_IPv4,
1948 BASE_NONE, NULL, 0x0, "", HFILL }},
1950 { &hf_isis_lsp_clv_mt,
1951 { "MT-ID ", "isis.lsp.clv_mt",
1952 FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
1955 { "Partition Repair", "isis.lsp.partition_repair", FT_BOOLEAN, 8,
1956 TFS(&supported_string), ISIS_LSP_PARTITION_MASK,
1957 "If set, this router supports the optional Partition Repair function", HFILL }},
1960 { "Attachment", "isis.lsp.att", FT_UINT8, BASE_DEC,
1961 NULL, ISIS_LSP_ATT_MASK,
1964 { &hf_isis_lsp_hippity,
1965 { "Overload bit", "isis.lsp.overload", FT_BOOLEAN, 8,
1966 TFS(&hippity_string), ISIS_LSP_HIPPITY_MASK,
1967 "If set, this router will not be used by any decision process to calculate routes", HFILL }},
1969 { &hf_isis_lsp_is_type,
1970 { "Type of Intermediate System", "isis.lsp.is_type", FT_UINT8, BASE_DEC,
1971 VALS(isis_lsp_istype_vals), ISIS_LSP_IS_TYPE_MASK,
1974 static gint *ett[] = {
1978 &ett_isis_lsp_clv_area_addr,
1979 &ett_isis_lsp_clv_is_neighbors,
1980 &ett_isis_lsp_clv_ext_is_reachability, /* CLV 22 */
1981 &ett_isis_lsp_part_of_clv_ext_is_reachability,
1982 &ett_isis_lsp_subclv_admin_group,
1983 &ett_isis_lsp_subclv_unrsv_bw,
1984 &ett_isis_lsp_clv_unknown,
1985 &ett_isis_lsp_clv_partition_dis,
1986 &ett_isis_lsp_clv_prefix_neighbors,
1987 &ett_isis_lsp_clv_auth,
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));