2 * Routines for decoding isis lsp packets and their CLVs
4 * $Id: packet-isis-lsp.c,v 1.42 2003/04/29 16:57:05 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_clv_ipv4_int_addr = -1;
49 static int hf_isis_lsp_clv_ipv6_int_addr = -1;
50 static int hf_isis_lsp_clv_te_router_id = -1;
51 static int hf_isis_lsp_clv_mt = -1;
52 static int hf_isis_lsp_p = -1;
53 static int hf_isis_lsp_att = -1;
54 static int hf_isis_lsp_hippity = -1;
55 static int hf_isis_lsp_is_type = -1;
57 static gint ett_isis_lsp = -1;
58 static gint ett_isis_lsp_info = -1;
59 static gint ett_isis_lsp_att = -1;
60 static gint ett_isis_lsp_clv_area_addr = -1;
61 static gint ett_isis_lsp_clv_is_neighbors = -1;
62 static gint ett_isis_lsp_clv_ext_is_reachability = -1; /* CLV 22 */
63 static gint ett_isis_lsp_part_of_clv_ext_is_reachability = -1;
64 static gint ett_isis_lsp_subclv_admin_group = -1;
65 static gint ett_isis_lsp_subclv_unrsv_bw = -1;
66 static gint ett_isis_lsp_clv_unknown = -1;
67 static gint ett_isis_lsp_clv_partition_dis = -1;
68 static gint ett_isis_lsp_clv_prefix_neighbors = -1;
69 static gint ett_isis_lsp_clv_nlpid = -1;
70 static gint ett_isis_lsp_clv_hostname = -1;
71 static gint ett_isis_lsp_clv_te_router_id = -1;
72 static gint ett_isis_lsp_clv_auth = -1;
73 static gint ett_isis_lsp_clv_ipv4_int_addr = -1;
74 static gint ett_isis_lsp_clv_ipv6_int_addr = -1; /* CLV 232 */
75 static gint ett_isis_lsp_clv_ip_reachability = -1;
76 static gint ett_isis_lsp_clv_ip_reach_subclv = -1;
77 static gint ett_isis_lsp_clv_ext_ip_reachability = -1; /* CLV 135 */
78 static gint ett_isis_lsp_part_of_clv_ext_ip_reachability = -1;
79 static gint ett_isis_lsp_clv_ipv6_reachability = -1; /* CLV 236 */
80 static gint ett_isis_lsp_part_of_clv_ipv6_reachability = -1;
81 static gint ett_isis_lsp_clv_mt = -1;
82 static gint ett_isis_lsp_clv_mt_is = -1;
83 static gint ett_isis_lsp_part_of_clv_mt_is = -1;
84 static gint ett_isis_lsp_clv_mt_reachable_IPv4_prefx = -1; /* CLV 235 */
85 static gint ett_isis_lsp_clv_mt_reachable_IPv6_prefx = -1; /* CLV 237 */
87 static const value_string isis_lsp_istype_vals[] = {
88 { ISIS_LSP_TYPE_UNUSED0, "Unused 0x0 (invalid)"},
89 { ISIS_LSP_TYPE_LEVEL_1, "Level 1"},
90 { ISIS_LSP_TYPE_UNUSED2, "Unused 0x2 (invalid)"},
91 { ISIS_LSP_TYPE_LEVEL_2, "Level 2"},
94 static const true_false_string supported_string = {
99 static const true_false_string hippity_string = {
106 * Predclare dissectors for use in clv dissection.
108 static void dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb,
109 proto_tree *tree, int offset, int id_length, int length);
110 static void dissect_lsp_partition_dis_clv(tvbuff_t *tvb,
111 proto_tree *tree, int offset, int id_length, int length);
112 static void dissect_lsp_mt_is_reachability_clv(tvbuff_t *tvb,
113 proto_tree *tree, int offset, int id_length, int length);
114 static void dissect_lsp_ext_is_reachability_clv(tvbuff_t *tvb,
115 proto_tree *tree, int offset, int id_length, int length);
116 static void dissect_lsp_l2_is_neighbors_clv(tvbuff_t *tvb,
117 proto_tree *tree, int offset, int id_length, int length);
118 static void dissect_lsp_l1_es_neighbors_clv(tvbuff_t *tvb,
119 proto_tree *tree, int offset, int id_length, int length);
120 static void dissect_lsp_l1_is_neighbors_clv(tvbuff_t *tvb,
121 proto_tree *tree, int offset, int id_length, int length);
122 static void dissect_lsp_area_address_clv(tvbuff_t *tvb,
123 proto_tree *tree, int offset, int id_length, int length);
124 static void dissect_lsp_l2_auth_clv(tvbuff_t *tvb,
125 proto_tree *tree, int offset, int id_length, int length);
126 static void dissect_lsp_l1_auth_clv(tvbuff_t *tvb,
127 proto_tree *tree, int offset, int id_length, int length);
128 static void dissect_lsp_ipv6_int_addr_clv(tvbuff_t *tvb,
129 proto_tree *tree, int offset, int id_length, int length);
130 static void dissect_lsp_ip_int_addr_clv(tvbuff_t *tvb,
131 proto_tree *tree, int offset, int id_length, int length);
132 static void dissect_lsp_te_router_id_clv(tvbuff_t *tvb,
133 proto_tree *tree, int offset, int id_length, int length);
134 static void dissect_lsp_hostname_clv(tvbuff_t *tvb,
135 proto_tree *tree, int offset, int id_length, int length);
136 static void dissect_lsp_mt_clv(tvbuff_t *tvb,
137 proto_tree *tree, int offset, int id_length, int length);
138 static void dissect_lsp_nlpid_clv(tvbuff_t *tvb,
139 proto_tree *tree, int offset, int id_length, int length);
140 static void dissect_lsp_ipv6_reachability_clv(tvbuff_t *tvb,
141 proto_tree *tree, int offset, int id_length, int length);
142 static void dissect_lsp_ext_ip_reachability_clv(tvbuff_t *tvb,
143 proto_tree *tree, int offset, int id_length, int length);
144 static void dissect_lsp_ip_reachability_clv(tvbuff_t *tvb,
145 proto_tree *tree, int offset, int id_length, int length);
146 static void dissect_ipreach_subclv(tvbuff_t *tvb,
147 proto_tree *tree, int offset, int clv_code, int clv_len);
148 static void dissect_lsp_mt_reachable_IPv4_prefx_clv(tvbuff_t *tvb,
149 proto_tree *tree, int offset, int id_length, int length);
150 static void dissect_lsp_mt_reachable_IPv6_prefx_clv(tvbuff_t *tvb,
151 proto_tree *tree, int offset, int id_length, int length);
154 static const isis_clv_handle_t clv_l1_lsp_opts[] = {
156 ISIS_CLV_L1_LSP_AREA_ADDRESS,
158 &ett_isis_lsp_clv_area_addr,
159 dissect_lsp_area_address_clv
162 ISIS_CLV_L1_LSP_IS_NEIGHBORS,
164 &ett_isis_lsp_clv_is_neighbors,
165 dissect_lsp_l1_is_neighbors_clv
168 ISIS_CLV_L1_LSP_ES_NEIGHBORS,
170 &ett_isis_lsp_clv_is_neighbors,
171 dissect_lsp_l1_es_neighbors_clv
174 ISIS_CLV_L1_LSP_EXT_IS_REACHABLE,
175 "Extended IS reachability",
176 &ett_isis_lsp_clv_ext_is_reachability,
177 dissect_lsp_ext_is_reachability_clv
180 ISIS_CLV_L1_LSP_IP_INT_REACHABLE,
181 "IP Internal reachability",
182 &ett_isis_lsp_clv_ip_reachability,
183 dissect_lsp_ip_reachability_clv
186 ISIS_CLV_L1_LSP_IP_EXT_REACHABLE,
187 "IP External reachability",
188 &ett_isis_lsp_clv_ip_reachability,
189 dissect_lsp_ip_reachability_clv
192 ISIS_CLV_L1_LSP_EXT_IP_REACHABLE,
193 "Extended IP Reachability",
194 &ett_isis_lsp_clv_ext_ip_reachability,
195 dissect_lsp_ext_ip_reachability_clv
198 ISIS_CLV_L1_LSP_IPv6_REACHABLE,
200 &ett_isis_lsp_clv_ipv6_reachability,
201 dissect_lsp_ipv6_reachability_clv
204 ISIS_CLV_L1_LSP_NLPID,
205 "Protocols supported",
206 &ett_isis_lsp_clv_nlpid,
207 dissect_lsp_nlpid_clv
210 ISIS_CLV_L1_LSP_HOSTNAME,
212 &ett_isis_lsp_clv_hostname,
213 dissect_lsp_hostname_clv
216 ISIS_CLV_L1_LSP_TE_ROUTER_ID,
217 "Traffic Engineering Router ID",
218 &ett_isis_lsp_clv_te_router_id,
219 dissect_lsp_te_router_id_clv
222 ISIS_CLV_L1_LSP_IP_INTERFACE_ADDR,
223 "IP Interface address(es)",
224 &ett_isis_lsp_clv_ipv4_int_addr,
225 dissect_lsp_ip_int_addr_clv
228 ISIS_CLV_L1_LSP_IPv6_INTERFACE_ADDR,
229 "IPv6 Interface address(es)",
230 &ett_isis_lsp_clv_ipv6_int_addr,
231 dissect_lsp_ipv6_int_addr_clv
234 ISIS_CLV_L1_LSP_AUTHENTICATION_NS,
235 "Authentication(non-spec)",
236 &ett_isis_lsp_clv_auth,
237 dissect_lsp_l1_auth_clv
240 ISIS_CLV_L1_LSP_AUTHENTICATION,
242 &ett_isis_lsp_clv_auth,
243 dissect_lsp_l1_auth_clv
248 &ett_isis_lsp_clv_mt,
252 ISIS_CLV_L1_LSP_MT_IS_REACHABLE,
253 "Multi Topology IS Reachability",
254 &ett_isis_lsp_clv_mt_is,
255 dissect_lsp_mt_is_reachability_clv
258 ISIS_CLV_L1_LSP_MT_REACHABLE_IPv4_PREFX,
259 "Multi Topology Reachable IPv4 Prefixes",
260 &ett_isis_lsp_clv_mt_reachable_IPv4_prefx,
261 dissect_lsp_mt_reachable_IPv4_prefx_clv
264 ISIS_CLV_L1_LSP_MT_REACHABLE_IPv6_PREFX,
265 "Multi Topology Reachable IPv6 Prefixes",
266 &ett_isis_lsp_clv_mt_reachable_IPv6_prefx,
267 dissect_lsp_mt_reachable_IPv6_prefx_clv
277 static const isis_clv_handle_t clv_l2_lsp_opts[] = {
279 ISIS_CLV_L1_LSP_AREA_ADDRESS,
281 &ett_isis_lsp_clv_area_addr,
282 dissect_lsp_area_address_clv
285 ISIS_CLV_L2_LSP_IS_NEIGHBORS,
287 &ett_isis_lsp_clv_is_neighbors,
288 dissect_lsp_l2_is_neighbors_clv
291 ISIS_CLV_L2_LSP_EXT_IS_REACHABLE,
292 "Extended IS reachability",
293 &ett_isis_lsp_clv_ext_is_reachability,
294 dissect_lsp_ext_is_reachability_clv
297 ISIS_CLV_L2_LSP_PARTITION_DIS,
298 "Parition Designated Level 2 IS",
299 &ett_isis_lsp_clv_partition_dis,
300 dissect_lsp_partition_dis_clv
303 ISIS_CLV_L2_LSP_PREFIX_NEIGHBORS,
305 &ett_isis_lsp_clv_prefix_neighbors,
306 dissect_lsp_prefix_neighbors_clv
309 ISIS_CLV_L2_LSP_IP_INT_REACHABLE,
310 "IP Internal reachability",
311 &ett_isis_lsp_clv_ip_reachability,
312 dissect_lsp_ip_reachability_clv
315 ISIS_CLV_L2_LSP_IP_EXT_REACHABLE,
316 "IP External reachability",
317 &ett_isis_lsp_clv_ip_reachability,
318 dissect_lsp_ip_reachability_clv
321 ISIS_CLV_L2_LSP_NLPID,
322 "Protocols supported",
323 &ett_isis_lsp_clv_nlpid,
324 dissect_lsp_nlpid_clv
327 ISIS_CLV_L2_LSP_HOSTNAME,
329 &ett_isis_lsp_clv_hostname,
330 dissect_lsp_hostname_clv
333 ISIS_CLV_L2_LSP_TE_ROUTER_ID,
334 "Traffic Engineering Router ID",
335 &ett_isis_lsp_clv_te_router_id,
336 dissect_lsp_te_router_id_clv
339 ISIS_CLV_L2_LSP_EXT_IP_REACHABLE,
340 "Extended IP Reachability",
341 &ett_isis_lsp_clv_ext_ip_reachability,
342 dissect_lsp_ext_ip_reachability_clv
345 ISIS_CLV_L2_LSP_IPv6_REACHABLE,
347 &ett_isis_lsp_clv_ipv6_reachability,
348 dissect_lsp_ipv6_reachability_clv
351 ISIS_CLV_L2_LSP_IP_INTERFACE_ADDR,
352 "IP Interface address(es)",
353 &ett_isis_lsp_clv_ipv4_int_addr,
354 dissect_lsp_ip_int_addr_clv
357 ISIS_CLV_L2_LSP_IPv6_INTERFACE_ADDR,
358 "IPv6 Interface address(es)",
359 &ett_isis_lsp_clv_ipv6_int_addr,
360 dissect_lsp_ipv6_int_addr_clv
363 ISIS_CLV_L2_LSP_AUTHENTICATION_NS,
364 "Authentication(non spec)",
365 &ett_isis_lsp_clv_auth,
366 dissect_lsp_l2_auth_clv
369 ISIS_CLV_L2_LSP_AUTHENTICATION,
371 &ett_isis_lsp_clv_auth,
372 dissect_lsp_l2_auth_clv
377 &ett_isis_lsp_clv_mt,
381 ISIS_CLV_L2_LSP_MT_IS_REACHABLE,
382 "Multi Topology IS Reachability",
383 &ett_isis_lsp_clv_mt_is,
384 dissect_lsp_mt_is_reachability_clv
387 ISIS_CLV_L2_LSP_MT_REACHABLE_IPv4_PREFX,
388 "Multi Topology Reachable IPv4 Prefixes",
389 &ett_isis_lsp_clv_mt_reachable_IPv4_prefx,
390 dissect_lsp_mt_reachable_IPv4_prefx_clv
393 ISIS_CLV_L2_LSP_MT_REACHABLE_IPv6_PREFX,
394 "Multi Topology Reachable IPv6 Prefixes",
395 &ett_isis_lsp_clv_mt_reachable_IPv6_prefx,
396 dissect_lsp_mt_reachable_IPv6_prefx_clv
407 * Name: dissect_lsp_mt_id()
410 * dissect and display the multi-topology ID value
413 * tvbuff_t * : tvbuffer for packet data
414 * proto_tree * : protocol display tree to fill out. CAN'T BE NULL
415 * int : offset into packet data where we are.
418 * void, but we will add to proto tree.
421 dissect_lsp_mt_id(tvbuff_t *tvb, proto_tree *tree, int offset)
426 /* fetch two bytes */
427 mt_block = tvb_get_ntohs(tvb, offset);
429 proto_tree_add_text ( tree, tvb, offset, 1 ,
430 "4 most significant bits reserved, should be set to 0 (%d)", ISIS_LSP_MT_MSHIP_RES(mt_block));
432 mt_id = ISIS_LSP_MT_MSHIP_ID(mt_block);
433 /*mask out the lower 12 bits */
436 strcpy(mt_desc,"'standard' topology");
439 strcpy(mt_desc,"IPv4 In-Band Management purposes");
442 strcpy(mt_desc,"IPv6 routing topology");
445 strcpy(mt_desc,"IPv4 multicast routing topology");
448 strcpy(mt_desc,"IPv6 multicast routing topology");
451 strcpy(mt_desc,((mt_block & 0x0fff) < 3996) ? "Reserved for IETF Consensus" : "Development, Experimental and Proprietary features");
454 proto_tree_add_text ( tree, tvb, offset, 2 ,
455 "%s (%d)", mt_desc, mt_id);
460 * Name: dissect_metric()
463 * Display a metric prefix portion. ISIS has the concept of multple
464 * metric per prefix (default, delay, expense, and error). This
465 * routine assists other dissectors by adding a single one of
466 * these to the display tree..
468 * The 8th(msbit) bit in the metric octet is the "supported" bit. The
469 * "default" support is required, so we support a "force_supported"
470 * flag that tells us that it MUST be zero (zero==supported,
471 * so it really should be a "not supported" in the boolean sense)
472 * and to display a protocol failure accordingly. Notably,
473 * Cisco IOS 12(6) blows this!
474 * The 7th bit must be zero (reserved).
477 * tvbuff_t * : tvbuffer for packet data
478 * proto_tree * : protocol display tree to fill out. May be NULL
479 * int : offset into packet data where we are.
480 * guint8 : value of the metric.
481 * char * : string giving type of the metric.
482 * int : force supported. True is the supported bit MUST be zero.
485 * void, but we will add to proto tree if !NULL.
488 dissect_metric(tvbuff_t *tvb, proto_tree *tree, int offset, guint8 value,
489 char *pstr, int force_supported )
495 s = ISIS_LSP_CLV_METRIC_SUPPORTED(value);
496 proto_tree_add_text(tree, tvb, offset, 1,
497 "%s Metric: %s%s %s%d:%d", pstr,
498 s ? "Not supported" : "Supported",
499 (s && force_supported) ? "(but is required to be)":"",
500 ISIS_LSP_CLV_METRIC_RESERVED(value) ? "(reserved bit != 0)":"",
501 ISIS_LSP_CLV_METRIC_VALUE(value), value );
505 * Name: dissect_lsp_ip_reachability_clv()
508 * Decode an IP reachability CLV. This can be either internal or
509 * external (the clv format does not change and which type we are
510 * displaying is put there by the dispatcher). All of these
511 * are a metric block followed by an IP addr and mask.
514 * tvbuff_t * : tvbuffer for packet data
515 * proto_tree * : proto tree to build on (may be null)
516 * int : current offset into packet data
517 * int : length of IDs in packet.
518 * int : length of this clv
521 * void, will modify proto_tree if not null.
524 dissect_lsp_ip_reachability_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
525 int id_length _U_, int length)
528 proto_tree *ntree = NULL;
529 guint32 src, mask, prefix_len;
531 guint32 bitmasks[33] = {
533 0x00000008, 0x0000000c, 0x0000000e, 0x0000000f,
534 0x000000f8, 0x000000fc, 0x000000fe, 0x000000ff,
535 0x000008ff, 0x00000cff, 0x00000eff, 0x00000fff,
536 0x0000f8ff, 0x0000fcff, 0x0000feff, 0x0000ffff,
537 0x0008ffff, 0x000cffff, 0x000effff, 0x000fffff,
538 0x00f8ffff, 0x00fcffff, 0x00feffff, 0x00ffffff,
539 0x08ffffff, 0x0cffffff, 0x0effffff, 0x0fffffff,
540 0xf8ffffff, 0xfcffffff, 0xfeffffff, 0xffffffff
544 while ( length > 0 ) {
546 isis_dissect_unknown(tvb, tree, offset,
547 "short IP reachability (%d vs 12)", length );
551 * Gotta build a sub-tree for all our pieces
554 tvb_memcpy(tvb, (guint8 *)&src, offset+4, 4);
555 tvb_memcpy(tvb, (guint8 *)&mask, offset+8, 4);
557 /* find out if the mask matches one of 33 possible prefix lengths */
561 while(prefix_len<=33) {
562 if (bitmasks[prefix_len++]==mask) {
568 /* 34 indicates no match -> must be a discontiguous netmask
569 lets dump the mask, otherwise print the prefix_len */
572 ti = proto_tree_add_text ( tree, tvb, offset, 12,
573 "IPv4 prefix: %s mask %s",
574 ip_to_str((guint8*)&src),
575 ip_to_str((guint8*)&mask));
577 ti = proto_tree_add_text ( tree, tvb, offset, 12,
578 "IPv4 prefix: %s/%d",
579 ip_to_str((guint8*)&src),
583 ntree = proto_item_add_subtree(ti,
584 ett_isis_lsp_clv_ip_reachability);
586 proto_tree_add_text (ntree, tvb, offset, 1,
587 "Default Metric: %d, %s, Distribution: %s",
588 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset)),
589 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset)) ? "External" : "Internal",
590 ISIS_LSP_CLV_METRIC_UPDOWN(tvb_get_guint8(tvb, offset)) ? "down" : "up");
593 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+1))) {
594 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: Not supported");
596 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: %d, %s",
597 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+1)),
598 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+1)) ? "External" : "Internal");
601 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+2))) {
602 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: Not supported");
604 proto_tree_add_text (ntree, tvb, offset+2, 1, "Exense Metric: %d, %s",
605 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+2)),
606 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+2)) ? "External" : "Internal");
609 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+3))) {
610 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: Not supported");
612 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: %d, %s",
613 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+3)),
614 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+3)) ? "External" : "Internal");
623 * Name: dissect_ipreach_subclv ()
625 * Description: parses IP reach subTLVs
626 * Called by various IP Reachability dissectors.
629 * tvbuff_t * : tvbuffer for packet data
630 * proto_tree * : protocol display tree to fill out.
631 * int : offset into packet data where we are (beginning of the sub_clv value).
637 dissect_ipreach_subclv(tvbuff_t *tvb, proto_tree *tree, int offset, int clv_code, int clv_len)
642 while (clv_len >= 4) {
643 proto_tree_add_text(tree, tvb, offset, 4,
644 "32-Bit Administrative tag: 0x%08x (=%u)",
645 tvb_get_ntohl(tvb, offset),
646 tvb_get_ntohl(tvb, offset));
652 while (clv_len >= 8) {
653 proto_tree_add_text(tree, tvb, offset, 8,
654 "64-Bit Administrative tag: 0x%08x%08x",
655 tvb_get_ntohl(tvb, offset),
656 tvb_get_ntohl(tvb, offset+4));
663 proto_tree_add_text (tree, tvb, offset, clv_len+2,
664 "Unknown sub-TLV: code %u, length %u",
672 * Name: dissect_lsp_ext_ip_reachability_clv()
674 * Description: Decode an Extended IP Reachability CLV - code 135.
676 * The extended IP reachability TLV is an extended version
677 * of the IP reachability TLVs (codes 128 and 130). It encodes
678 * the metric as a 32-bit unsigned interger and allows to add
681 * CALLED BY TLV 235 DISSECTOR
685 * tvbuff_t * : tvbuffer for packet data
686 * proto_tree * : proto tree to build on (may be null)
687 * int : current offset into packet data
688 * int : length of IDs in packet.
689 * int : length of this clv
692 * void, will modify proto_tree if not null.
695 dissect_lsp_ext_ip_reachability_clv(tvbuff_t *tvb, proto_tree *tree,
696 int offset, int id_length _U_, int length)
698 proto_item *pi = NULL;
699 proto_tree *subtree = NULL;
700 proto_tree *subtree2 = NULL;
702 guint8 bit_length, byte_length;
707 guint8 clv_code, clv_len;
712 memset (prefix, 0, 4);
713 ctrl_info = tvb_get_guint8(tvb, offset+4);
714 bit_length = ctrl_info & 0x3f;
715 byte_length = (bit_length + 7) / 8;
716 tvb_memcpy (tvb, prefix, offset+5, byte_length);
717 metric = tvb_get_ntohl(tvb, offset);
719 if ((ctrl_info & 0x40) != 0)
720 subclvs_len = 1+tvb_get_guint8(tvb, offset+5+byte_length);
722 pi = proto_tree_add_text (tree, tvb, offset, 5+byte_length+subclvs_len,
723 "IPv4 prefix: %s/%d, Metric: %u, Distribution: %s, %ssub-TLVs present",
727 ((ctrl_info & 0x80) == 0) ? "up" : "down",
728 ((ctrl_info & 0x40) == 0) ? "no " : "" );
730 /* open up a new tree per prefix */
731 subtree = proto_item_add_subtree (pi, ett_isis_lsp_part_of_clv_ext_ip_reachability);
733 proto_tree_add_text (subtree, tvb, offset+5, byte_length, "IPv4 prefix: %s/%u",
737 proto_tree_add_text (subtree, tvb, offset, 4, "Metric: %u", metric);
739 proto_tree_add_text (subtree, tvb, offset+4, 1, "Distribution: %s",
740 ((ctrl_info & 0x80) == 0) ? "up" : "down");
742 len = 5 + byte_length;
743 if ((ctrl_info & 0x40) != 0) {
744 subclvs_len = tvb_get_guint8(tvb, offset+len);
745 pi = proto_tree_add_text (subtree, tvb, offset+len, 1, "sub-TLVs present, total length: %u bytes",
747 proto_item_set_len (pi, subclvs_len+1);
748 /* open up a new tree for the subTLVs */
749 subtree2 = proto_item_add_subtree (pi, ett_isis_lsp_clv_ip_reach_subclv);
752 while (i < subclvs_len) {
753 clv_code = tvb_get_guint8(tvb, offset+len+1); /* skip the total subtlv len indicator */
754 clv_len = tvb_get_guint8(tvb, offset+len+2);
757 * we pass on now the raw data to the ipreach_subtlv dissector
758 * therefore we need to skip 3 bytes
759 * (total subtlv len, subtlv type, subtlv len)
761 dissect_ipreach_subclv(tvb, subtree2, offset+len+3, clv_code, clv_len);
764 len += 1 + subclvs_len;
766 proto_tree_add_text (subtree, tvb, offset+4, 1, "no sub-TLVs present");
767 proto_item_set_len (pi, len);
776 * Name: dissect_lsp_ipv6_reachability_clv()
778 * Description: Decode an IPv6 reachability CLV - code 236.
780 * CALLED BY TLV 237 DISSECTOR
783 * tvbuff_t * : tvbuffer for packet data
784 * proto_tree * : proto tree to build on (may be null)
785 * int : current offset into packet data
786 * int : length of IDs in packet.
787 * int : length of this clv
790 * void, will modify proto_tree if not null.
793 dissect_lsp_ipv6_reachability_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
794 int id_length _U_, int length)
797 proto_tree *subtree = NULL;
798 proto_tree *subtree2 = NULL;
800 guint8 bit_length, byte_length;
801 struct e_in6_addr prefix;
805 guint8 clv_code, clv_len;
809 memset (prefix.s6_addr, 0, 16);
812 ctrl_info = tvb_get_guint8(tvb, offset+4);
813 bit_length = tvb_get_guint8(tvb, offset+5);
814 byte_length = (bit_length + 7) / 8;
815 tvb_memcpy (tvb, prefix.s6_addr, offset+6, byte_length);
816 metric = tvb_get_ntohl(tvb, offset);
818 if ((ctrl_info & 0x20) != 0)
819 subclvs_len = 1+tvb_get_guint8(tvb, offset+6+byte_length);
821 pi = proto_tree_add_text (tree, tvb, offset, 6+byte_length+subclvs_len,
822 "IPv6 prefix: %s/%u, Metric: %u, Distribution: %s, %s, %ssub-TLVs present",
823 ip6_to_str (&prefix),
826 ((ctrl_info & 0x80) == 0) ? "up" : "down",
827 ((ctrl_info & 0x40) == 0) ? "internal" : "external",
828 ((ctrl_info & 0x20) == 0) ? "no " : "" );
830 subtree = proto_item_add_subtree (pi, ett_isis_lsp_part_of_clv_ipv6_reachability);
832 proto_tree_add_text (subtree, tvb, offset+6, byte_length, "IPv6 prefix: %s/%u",
833 ip6_to_str (&prefix),
836 proto_tree_add_text (subtree, tvb, offset, 4,
837 "Metric: %u", metric);
839 proto_tree_add_text (subtree, tvb, offset+4, 1,
840 "Distribution: %s, %s",
841 ((ctrl_info & 0x80) == 0) ? "up" : "down",
842 ((ctrl_info & 0x40) == 0) ? "internal" : "external" );
844 if ((ctrl_info & 0x1f) != 0) {
845 proto_tree_add_text (subtree, tvb, offset+4, 1,
846 "Reserved bits: 0x%x",
847 (ctrl_info & 0x1f) );
850 len = 6 + byte_length;
851 if ((ctrl_info & 0x20) != 0) {
852 subclvs_len = tvb_get_guint8(tvb, offset+len);
853 pi = proto_tree_add_text (subtree, tvb, offset+len, 1, "sub-TLVs present, total length: %u bytes",
855 proto_item_set_len (pi, subclvs_len+1);
856 /* open up a new tree for the subTLVs */
857 subtree2 = proto_item_add_subtree (pi, ett_isis_lsp_clv_ip_reach_subclv);
860 while (i < subclvs_len) {
861 clv_code = tvb_get_guint8(tvb, offset+len+1); /* skip the total subtlv len indicator */
862 clv_len = tvb_get_guint8(tvb, offset+len+2);
863 dissect_ipreach_subclv(tvb, subtree2, offset+len+3, clv_code, clv_len);
866 len += 1 + subclvs_len;
868 proto_tree_add_text (subtree, tvb, offset+4, 1, "no sub-TLVs present");
869 proto_item_set_len (pi, len);
877 * Name: dissect_lsp_nlpid_clv()
880 * Decode for a lsp packets NLPID clv. Calls into the
884 * tvbuff_t * : tvbuffer for packet data
885 * proto_tree * : proto tree to build on (may be null)
886 * int : current offset into packet data
887 * int : length of IDs in packet.
888 * int : length of this clv
891 * void, will modify proto_tree if not null.
894 dissect_lsp_nlpid_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
895 int id_length _U_, int length)
897 isis_dissect_nlpid_clv(tvb, tree, offset, length);
901 * Name: dissect_lsp_mt_clv()
903 * Description: - code 229
904 * Decode for a lsp packets Multi Topology clv. Calls into the
908 * tvbuff_t * : tvbuffer for packet data
909 * proto_tree * : proto tree to build on (may be null)
910 * int : current offset into packet data
911 * guint : length of this clv
912 * int : length of IDs in packet.
915 * void, will modify proto_tree if not null.
918 dissect_lsp_mt_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
919 int id_length _U_, int length)
921 isis_dissect_mt_clv(tvb, tree, offset, length, hf_isis_lsp_clv_mt );
925 * Name: dissect_lsp_hostname_clv()
928 * Decode for a lsp packets hostname clv. Calls into the
932 * tvbuff_t * : tvbuffer for packet data
933 * proto_tree * : proto tree to build on (may be null)
934 * int : current offset into packet data
935 * int : length of IDs in packet.
936 * int : length of this clv
939 * void, will modify proto_tree if not null.
942 dissect_lsp_hostname_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
943 int id_length _U_, int length)
945 isis_dissect_hostname_clv(tvb, tree, offset, length);
950 * Name: dissect_lsp_te_router_id_clv()
953 * Decode for a lsp packets Traffic Engineering ID clv. Calls into the
957 * tvbuff_t * : tvbuffer for packet data
958 * proto_tree * : proto tree to build on (may be null)
959 * int : current offset into packet data
960 * int : length of IDs in packet.
961 * int : length of this clv
964 * void, will modify proto_tree if not null.
967 dissect_lsp_te_router_id_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
968 int id_length _U_, int length)
970 isis_dissect_te_router_id_clv(tvb, tree, offset, length,
971 hf_isis_lsp_clv_te_router_id );
976 * Name: dissect_lsp_ip_int_addr_clv()
979 * Decode for a lsp packets ip interface addr clv. Calls into the
983 * tvbuff_t * : tvbuffer for packet data
984 * proto_tree * : proto tree to build on (may be null)
985 * int : current offset into packet data
986 * int : length of IDs in packet.
987 * int : length of this clv
990 * void, will modify proto_tree if not null.
993 dissect_lsp_ip_int_addr_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
994 int id_length _U_, int length)
996 isis_dissect_ip_int_clv(tvb, tree, offset, length,
997 hf_isis_lsp_clv_ipv4_int_addr );
1001 * Name: dissect_lsp_ipv6_int_addr_clv()
1003 * Description: Decode an IPv6 interface addr CLV - code 232.
1005 * Calls into the clv common one.
1008 * tvbuff_t * : tvbuffer for packet data
1009 * proto_tree * : proto tree to build on (may be null)
1010 * int : current offset into packet data
1011 * int : length of IDs in packet.
1012 * int : length of this clv
1015 * void, will modify proto_tree if not null.
1018 dissect_lsp_ipv6_int_addr_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1019 int id_length _U_, int length)
1021 isis_dissect_ipv6_int_clv(tvb, tree, offset, length,
1022 hf_isis_lsp_clv_ipv6_int_addr );
1026 * Name: dissect_lsp_L1_auth_clv()
1029 * Decode for a lsp packets authenticaion clv. Calls into the
1030 * clv common one. An auth inside a L1 LSP is a per area password
1033 * tvbuff_t * : tvbuffer for packet data
1034 * proto_tree * : proto tree to build on (may be null)
1035 * int : current offset into packet data
1036 * int : length of IDs in packet.
1037 * int : length of this clv
1040 * void, will modify proto_tree if not null.
1043 dissect_lsp_l1_auth_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1044 int id_length _U_, int length)
1046 isis_dissect_authentication_clv(tvb, tree, offset, length,
1047 "Per area authentication" );
1051 * Name: dissect_lsp_L2_auth_clv()
1054 * Decode for a lsp packets authenticaion clv. Calls into the
1055 * clv common one. An auth inside a L2 LSP is a per domain password
1058 * tvbuff_t * : tvbuffer for packet data
1059 * proto_tree * : proto tree to build on (may be null)
1060 * int : current offset into packet data
1061 * int : length of IDs in packet.
1062 * int : length of this clv
1065 * void, will modify proto_tree if not null.
1068 dissect_lsp_l2_auth_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1069 int id_length _U_, int length)
1071 isis_dissect_authentication_clv(tvb, tree, offset, length,
1072 "Per domain authentication" );
1076 * Name: dissect_lsp_area_address_clv()
1079 * Decode for a lsp packet's area address clv. Call into clv common
1083 * tvbuff_t * : tvbuffer for packet data
1084 * proto_tree * : protocol display tree to fill out. May be NULL
1085 * int : offset into packet data where we are.
1086 * int : length of IDs in packet.
1087 * int : length of clv we are decoding
1090 * void, but we will add to proto tree if !NULL.
1093 dissect_lsp_area_address_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1094 int id_length _U_, int length)
1096 isis_dissect_area_address_clv(tvb, tree, offset, length);
1100 * Name: dissect_lsp_eis_neighbors_clv_inner()
1103 * Real work horse for showing neighbors. This means we decode the
1104 * first octet as either virtual/!virtual (if show_virtual param is
1105 * set), or as a must == 0 reserved value.
1107 * Once past that, we decode n neighbor elements. Each neighbor
1108 * is comprised of a metric block (is dissect_metric) and the
1112 * tvbuff_t * : tvbuffer for packet data
1113 * proto_tree * : protocol display tree to fill out. May be NULL
1114 * int : offset into packet data where we are.
1115 * int : length of IDs in packet.
1116 * int : length of clv we are decoding
1117 * int : set to decode first octet as virtual vs reserved == 0
1118 * int : set to indicate EIS instead of IS (6 octet per addr instead of 7)
1121 * void, but we will add to proto tree if !NULL.
1124 dissect_lsp_eis_neighbors_clv_inner(tvbuff_t *tvb, proto_tree *tree,
1125 int offset, int length, int id_length, int show_virtual, int is_eis)
1128 proto_tree *ntree = NULL;
1132 id_length++; /* IDs are one octet longer in IS neighbours */
1134 if ( show_virtual ) {
1135 /* virtual path flag */
1136 proto_tree_add_text ( tree, tvb, offset, 1,
1137 tvb_get_guint8(tvb, offset) ? "IsVirtual" : "IsNotVirtual" );
1139 proto_tree_add_text ( tree, tvb, offset, 1,
1140 "Reserved value 0x%02x, must == 0",
1141 tvb_get_guint8(tvb, offset) );
1147 tlen = 4 + id_length;
1149 while ( length > 0 ) {
1151 isis_dissect_unknown(tvb, tree, offset,
1152 "short E/IS reachability (%d vs %d)", length,
1157 * Gotta build a sub-tree for all our pieces
1161 ti = proto_tree_add_text(tree, tvb, offset, tlen,
1163 print_system_id( tvb_get_ptr(tvb, offset+4, id_length), id_length ) );
1165 ti = proto_tree_add_text(tree, tvb, offset, tlen,
1167 print_system_id(tvb_get_ptr(tvb, offset+4, id_length), id_length ) );
1169 ntree = proto_item_add_subtree(ti,
1170 ett_isis_lsp_clv_is_neighbors);
1174 proto_tree_add_text (ntree, tvb, offset, 1,
1175 "Default Metric: %d, %s",
1176 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset)),
1177 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset)) ? "External" : "Internal");
1179 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+1))) {
1180 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: Not supported");
1182 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: %d, %s",
1183 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+1)),
1184 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+1)) ? "External" : "Internal");
1188 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+2))) {
1189 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: Not supported");
1191 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: %d, %s",
1192 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+2)),
1193 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+2)) ? "External" : "Internal");
1196 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+3))) {
1197 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: Not supported");
1199 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: %d, %s",
1200 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+3)),
1201 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+3)) ? "External" : "Internal");
1211 * Name: dissect_lsp_l1_is_neighbors_clv()
1214 * Dispatch a l1 intermediate system neighbor by calling
1215 * the inner function with show virtual set to TRUE and is es set to FALSE.
1218 * tvbuff_t * : tvbuffer for packet data
1219 * proto_tree * : protocol display tree to fill out. May be NULL
1220 * int : offset into packet data where we are.
1221 * int : length of IDs in packet.
1222 * int : length of clv we are decoding
1225 * void, but we will add to proto tree if !NULL.
1228 dissect_lsp_l1_is_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1229 int id_length, int length)
1231 dissect_lsp_eis_neighbors_clv_inner(tvb, tree, offset,
1232 length, id_length, TRUE, FALSE);
1236 * Name: dissect_lsp_l1_es_neighbors_clv()
1239 * Dispatch a l1 end or intermediate system neighbor by calling
1240 * the inner function with show virtual set to TRUE and es set to TRUE.
1243 * tvbuff_t * : tvbuffer for packet data
1244 * proto_tree * : protocol display tree to fill out. May be NULL
1245 * int : offset into packet data where we are.
1246 * int : length of IDs in packet.
1247 * int : length of clv we are decoding
1250 * void, but we will add to proto tree if !NULL.
1253 dissect_lsp_l1_es_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1254 int id_length, int length)
1256 dissect_lsp_eis_neighbors_clv_inner(tvb, tree, offset,
1257 length, id_length, TRUE, TRUE);
1261 * Name: dissect_lsp_l2_is_neighbors_clv()
1264 * Dispatch a l2 intermediate system neighbor by calling
1265 * the inner function with show virtual set to FALSE, and is es set
1269 * tvbuff_t * : tvbuffer for packet data
1270 * proto_tree * : protocol display tree to fill out. May be NULL
1271 * int : offset into packet data where we are.
1272 * int : length of IDs in packet.
1273 * int : length of clv we are decoding
1276 * void, but we will add to proto tree if !NULL.
1279 dissect_lsp_l2_is_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1280 int id_length, int length)
1282 dissect_lsp_eis_neighbors_clv_inner(tvb, tree, offset,
1283 length, id_length, FALSE, FALSE);
1288 * Name: dissect_subclv_admin_group ()
1290 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1292 * This function is called by dissect_lsp_ext_is_reachability_clv()
1293 * for dissect the administrive group sub-CLV (code 3).
1296 * tvbuff_t * : tvbuffer for packet data
1297 * proto_tree * : protocol display tree to fill out.
1298 * int : offset into packet data where we are (beginning of the sub_clv value).
1304 dissect_subclv_admin_group (tvbuff_t *tvb, proto_tree *tree, int offset) {
1311 ti = proto_tree_add_text(tree, tvb, offset-2, 6, "Administrative group(s):");
1312 ntree = proto_item_add_subtree (ti, ett_isis_lsp_subclv_admin_group);
1314 clv_value = tvb_get_ntohl(tvb, offset);
1316 for (i = 0 ; i < 32 ; i++) {
1317 if ( (clv_value & mask) != 0 ) {
1318 proto_tree_add_text (ntree, tvb, offset, 4, "group %d", i);
1325 * Name: dissect_subclv_max_bw ()
1327 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1329 * This function is called by dissect_lsp_ext_is_reachability_clv()
1330 * for dissect the maximum link bandwidth sub-CLV (code 9).
1333 * tvbuff_t * : tvbuffer for packet data
1334 * proto_tree * : protocol display tree to fill out.
1335 * int : offset into packet data where we are (beginning of the sub_clv value).
1341 dissect_subclv_max_bw(tvbuff_t *tvb, proto_tree *tree, int offset)
1345 bw = tvb_get_ntohieee_float(tvb, offset);
1346 proto_tree_add_text (tree, tvb, offset-2, 6,
1347 "Maximum link bandwidth : %.2f Mbps", bw*8/1000000 );
1351 * Name: dissect_subclv_rsv_bw ()
1353 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1355 * This function is called by dissect_lsp_ext_is_reachability_clv()
1356 * for dissect the reservable link bandwidth sub-CLV (code 10).
1359 * tvbuff_t * : tvbuffer for packet data
1360 * proto_tree * : protocol display tree to fill out.
1361 * int : offset into packet data where we are (beginning of the sub_clv value).
1367 dissect_subclv_rsv_bw(tvbuff_t *tvb, proto_tree *tree, int offset)
1371 bw = tvb_get_ntohieee_float(tvb, offset);
1372 proto_tree_add_text (tree, tvb, offset-2, 6,
1373 "Reservable link bandwidth: %.2f Mbps", bw*8/1000000 );
1377 * Name: dissect_subclv_unrsv_bw ()
1379 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1381 * This function is called by dissect_lsp_ext_is_reachability_clv()
1382 * for dissect the unreserved bandwidth sub-CLV (code 11).
1385 * tvbuff_t * : tvbuffer for packet data
1386 * proto_tree * : protocol display tree to fill out.
1387 * int : offset into packet data where we are (beginning of the sub_clv value).
1393 dissect_subclv_unrsv_bw(tvbuff_t *tvb, proto_tree *tree, int offset)
1400 ti = proto_tree_add_text (tree, tvb, offset-2, 34, "Unreserved bandwidth:");
1401 ntree = proto_item_add_subtree (ti, ett_isis_lsp_subclv_unrsv_bw);
1403 for (i = 0 ; i < 8 ; i++) {
1404 bw = tvb_get_ntohieee_float(tvb, offset+4*i);
1405 proto_tree_add_text (ntree, tvb, offset+4*i, 4,
1406 "priority level %d: %.2f Mbps", i, bw*8/1000000 );
1411 * Name: dissect_lsp_ext_is_reachability_clv()
1413 * Description: Decode a Extended IS Reachability CLV - code 22
1415 * The extended IS reachability TLV is an extended version
1416 * of the IS reachability TLV (code 2). It encodes the metric
1417 * as a 24-bit unsigned interger and allows to add sub-CLV(s).
1419 * CALLED BY TLV 222 DISSECTOR
1422 * tvbuff_t * : tvbuffer for packet data
1423 * proto_tree * : protocol display tree to fill out. May be NULL
1424 * int : offset into packet data where we are.
1425 * int : length of IDs in packet.
1426 * int : length of clv we are decoding
1429 * void, but we will add to proto tree if !NULL.
1432 dissect_lsp_ext_is_reachability_clv(tvbuff_t *tvb, proto_tree *tree,
1433 int offset, int id_length _U_, int length)
1436 proto_tree *ntree = NULL;
1439 guint8 clv_code, clv_len;
1443 while (length > 0) {
1444 ti = proto_tree_add_text (tree, tvb, offset, -1,
1446 print_system_id (tvb_get_ptr(tvb, offset, 7), 7) );
1447 ntree = proto_item_add_subtree (ti,
1448 ett_isis_lsp_part_of_clv_ext_is_reachability );
1450 proto_tree_add_text (ntree, tvb, offset+7, 3,
1451 "Metric: %d", tvb_get_ntoh24(tvb, offset+7) );
1453 subclvs_len = tvb_get_guint8(tvb, offset+10);
1454 if (subclvs_len == 0) {
1455 proto_tree_add_text (ntree, tvb, offset+10, 1, "no sub-TLVs present");
1459 while (i < subclvs_len) {
1460 clv_code = tvb_get_guint8(tvb, offset+11+i);
1461 clv_len = tvb_get_guint8(tvb, offset+12+i);
1464 dissect_subclv_admin_group(tvb, ntree, offset+13+i);
1467 proto_tree_add_text (ntree, tvb, offset+11+i, 6,
1468 "IPv4 interface address: %s", ip_to_str (tvb_get_ptr(tvb, offset+13+i, 4)) );
1471 proto_tree_add_text (ntree, tvb, offset+11+i, 6,
1472 "IPv4 neighbor address: %s", ip_to_str (tvb_get_ptr(tvb, offset+13+i, 4)) );
1475 dissect_subclv_max_bw (tvb, ntree, offset+13+i);
1478 dissect_subclv_rsv_bw (tvb, ntree, offset+13+i);
1481 dissect_subclv_unrsv_bw (tvb, ntree, offset+13+i);
1484 proto_tree_add_text (ntree, tvb, offset+11+i, 5,
1485 "Traffic engineering default metric: %d",
1486 tvb_get_ntoh24(tvb, offset+13+i) );
1493 proto_tree_add_text (ntree, tvb, offset+11+i, clv_len+2,
1494 "Unknown Cisco specific extensions: code %d, length %d",
1495 clv_code, clv_len );
1498 proto_tree_add_text (ntree, tvb, offset+11+i, clv_len+2,
1499 "Unknown sub-CLV: code %d, length %d", clv_code, clv_len );
1506 len = 11 + subclvs_len;
1507 proto_item_set_len (ti, len);
1514 * Name: dissect_lsp_mt_reachable_IPv4_prefx_clv()
1516 * Description: Decode Multi-Topology IPv4 Prefixes - code 235
1520 * tvbuff_t * : tvbuffer for packet data
1521 * proto_tree * : protocol display tree to fill out. May be NULL
1522 * int : offset into packet data where we are.
1523 * int : length of IDs in packet.
1524 * int : length of clv we are decoding
1527 * void, but we will add to proto tree if !NULL.
1530 dissect_lsp_mt_reachable_IPv4_prefx_clv(tvbuff_t *tvb,
1531 proto_tree *tree, int offset, int id_length _U_, int length)
1535 isis_dissect_unknown(tvb, tree, offset,
1536 "short lsp multi-topology reachable IPv4 prefixes(%d vs %d)", length,
1540 dissect_lsp_mt_id(tvb, tree, offset);
1541 dissect_lsp_ext_ip_reachability_clv(tvb, tree, offset+2, 0, length-2);
1545 * Name: dissect_lsp_mt_reachable_IPv6_prefx_clv()
1547 * Description: Decode Multi-Topology IPv6 Prefixes - code 237
1551 * tvbuff_t * : tvbuffer for packet data
1552 * proto_tree * : protocol display tree to fill out. May be NULL
1553 * int : offset into packet data where we are.
1554 * int : length of IDs in packet.
1555 * int : length of clv we are decoding
1558 * void, but we will add to proto tree if !NULL.
1561 dissect_lsp_mt_reachable_IPv6_prefx_clv(tvbuff_t *tvb,
1562 proto_tree *tree, int offset, int id_length _U_, int length)
1566 isis_dissect_unknown(tvb, tree, offset,
1567 "short lsp multi-topology reachable IPv6 prefixes(%d vs %d)", length,
1571 dissect_lsp_mt_id(tvb, tree, offset);
1572 dissect_lsp_ipv6_reachability_clv(tvb, tree, offset+2, 0, length-2);
1577 * Name: dissect_lsp_mt_is_reachability_clv()
1579 * Description: Decode Multi-Topology Intermediate Systems - code 222
1583 * tvbuff_t * : tvbuffer for packet data
1584 * proto_tree * : protocol display tree to fill out. May be NULL
1585 * int : offset into packet data where we are.
1587 * int : length of clv we are decoding
1590 * void, but we will add to proto tree if !NULL.
1594 dissect_lsp_mt_is_reachability_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1595 int id_length _U_, int length)
1599 isis_dissect_unknown(tvb, tree, offset,
1600 "short lsp reachability(%d vs %d)", length,
1606 * the MT ID value dissection is used in other LSPs so we push it
1609 dissect_lsp_mt_id(tvb, tree, offset);
1611 * fix here. No need to parse TLV 22 (with bugs) while it is
1612 * already done correctly!!
1614 dissect_lsp_ext_is_reachability_clv(tvb, tree, offset+2, 0, length-2);
1618 * Name: dissect_lsp_partition_dis_clv()
1621 * This CLV is used to indicate which system is the designated
1622 * IS for partition repair. This means just putting out the
1623 * "id_length"-octet IS.
1626 * tvbuff_t * : tvbuffer for packet data
1627 * proto_tree * : protocol display tree to fill out. May be NULL
1628 * int : offset into packet data where we are.
1629 * int : length of IDs in packet.
1630 * int : length of clv we are decoding
1633 * void, but we will add to proto tree if !NULL.
1636 dissect_lsp_partition_dis_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1637 int id_length, int length)
1639 if ( length < id_length ) {
1640 isis_dissect_unknown(tvb, tree, offset,
1641 "short lsp partition DIS(%d vs %d)", length,
1646 * Gotta build a sub-tree for all our pieces
1649 proto_tree_add_text ( tree, tvb, offset, id_length,
1650 "Partition designated L2 IS: %s",
1651 print_system_id( tvb_get_ptr(tvb, offset, id_length), id_length ) );
1653 length -= id_length;
1654 offset += id_length;
1656 isis_dissect_unknown(tvb, tree, offset,
1657 "Long lsp partition DIS, %d left over", length );
1663 * Name: dissect_lsp_prefix_neighbors_clv()
1666 * The prefix CLV describes what other (OSI) networks we can reach
1667 * and what their cost is. It is built from a metric block
1668 * (see dissect_metric) followed by n addresses.
1671 * tvbuff_t * : tvbuffer for packet data
1672 * proto_tree * : protocol display tree to fill out. May be NULL
1673 * int : offset into packet data where we are.
1674 * int : length of IDs in packet.
1675 * int : length of clv we are decoding
1678 * void, but we will add to proto tree if !NULL.
1681 dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1682 int id_length _U_, int length)
1688 isis_dissect_unknown(tvb, tree, offset,
1689 "Short lsp prefix neighbors (%d vs 4)", length );
1693 dissect_metric (tvb, tree, offset,
1694 tvb_get_guint8(tvb, offset), "Default", TRUE );
1695 dissect_metric (tvb, tree, offset+1,
1696 tvb_get_guint8(tvb, offset+1), "Delay", FALSE );
1697 dissect_metric (tvb, tree, offset+2,
1698 tvb_get_guint8(tvb, offset+2), "Expense", FALSE );
1699 dissect_metric (tvb, tree, offset+3,
1700 tvb_get_guint8(tvb, offset+3), "Error", FALSE );
1704 while ( length > 0 ) {
1705 mylen = tvb_get_guint8(tvb, offset);
1708 isis_dissect_unknown(tvb, tree, offset,
1709 "Zero payload space after length in prefix neighbor" );
1712 if ( mylen > length) {
1713 isis_dissect_unknown(tvb, tree, offset,
1714 "Interal length of prefix neighbor too long (%d vs %d)",
1720 * Lets turn the area address into "standard" 0000.0000.etc
1723 sbuf = print_area( tvb_get_ptr(tvb, offset+1, mylen), mylen );
1724 /* and spit it out */
1726 proto_tree_add_text ( tree, tvb, offset, mylen + 1,
1727 "Area address (%d): %s", mylen, sbuf );
1729 offset += mylen + 1;
1730 length -= mylen; /* length already adjusted for len fld*/
1735 * Name: isis_dissect_isis_lsp()
1738 * Print out the LSP part of the main header and then call the CLV
1739 * de-mangler with the right list of valid CLVs.
1742 * tvbuff_t * : tvbuffer for packet data
1743 * proto_tree * : protocol display tree to add to. May be NULL.
1744 * int offset : our offset into packet data.
1745 * int : LSP type, a la packet-isis.h ISIS_TYPE_* values
1746 * int : header length of packet.
1747 * int : length of IDs in packet.
1750 * void, but we will add to proto tree if !NULL.
1753 isis_dissect_isis_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
1754 int lsp_type, int header_length, int id_length)
1756 proto_item *ti, *to, *ta;
1757 proto_tree *lsp_tree = NULL, *info_tree, *att_tree;
1759 guint8 lsp_info, lsp_att;
1763 ti = proto_tree_add_text(tree, tvb, offset, -1,
1765 lsp_tree = proto_item_add_subtree(ti, ett_isis_lsp);
1768 pdu_length = tvb_get_ntohs(tvb, offset);
1770 proto_tree_add_uint(lsp_tree, hf_isis_lsp_pdu_length, tvb,
1771 offset, 2, pdu_length);
1776 proto_tree_add_text(lsp_tree, tvb, offset, 2,
1777 "Remaining Lifetime: %us",
1778 tvb_get_ntohs(tvb, offset));
1783 proto_tree_add_text(lsp_tree, tvb, offset, id_length + 2,
1785 print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) );
1788 if (check_col(pinfo->cinfo, COL_INFO)) {
1789 col_append_fstr(pinfo->cinfo, COL_INFO, ", LSP-ID: %s",
1790 print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) );
1792 offset += id_length + 2;
1795 proto_tree_add_uint(lsp_tree, hf_isis_lsp_sequence_number, tvb,
1797 tvb_get_ntohl(tvb, offset));
1799 if (check_col(pinfo->cinfo, COL_INFO)) {
1800 col_append_fstr(pinfo->cinfo, COL_INFO, ", Sequence: 0x%08x, Lifetime: %5us",
1801 tvb_get_ntohl(tvb, offset),
1802 tvb_get_ntohs(tvb, offset - (id_length+2+2)));
1807 /* XXX -> we could validate the cksum here! */
1808 proto_tree_add_uint(lsp_tree, hf_isis_lsp_checksum, tvb,
1809 offset, 2, tvb_get_ntohs(tvb, offset));
1815 * P | ATT | HIPPITY | IS TYPE description.
1817 lsp_info = tvb_get_guint8(tvb, offset);
1818 to = proto_tree_add_text(lsp_tree, tvb, offset, 1,
1819 "Type block(0x%02x): Partition Repair:%d, Attached bits:%d, Overload bit:%d, IS type:%d",
1821 ISIS_LSP_PARTITION(lsp_info),
1822 ISIS_LSP_ATT(lsp_info),
1823 ISIS_LSP_HIPPITY(lsp_info),
1824 ISIS_LSP_IS_TYPE(lsp_info)
1827 info_tree = proto_item_add_subtree(to, ett_isis_lsp_info);
1828 proto_tree_add_boolean(info_tree, hf_isis_lsp_p, tvb, offset, 1, lsp_info);
1829 ta = proto_tree_add_uint(info_tree, hf_isis_lsp_att, tvb, offset, 1, lsp_info);
1830 att_tree = proto_item_add_subtree(ta, ett_isis_lsp_att);
1831 lsp_att = ISIS_LSP_ATT(lsp_info);
1832 proto_tree_add_text(att_tree, tvb, offset, 1,
1833 "%d... = Default metric: %s", ISIS_LSP_ATT_DEFAULT(lsp_att), ISIS_LSP_ATT_DEFAULT(lsp_att) ? "Set" : "Unset");
1834 proto_tree_add_text(att_tree, tvb, offset, 1,
1835 ".%d.. = Delay metric: %s", ISIS_LSP_ATT_DELAY(lsp_att), ISIS_LSP_ATT_DELAY(lsp_att) ? "Set" : "Unset");
1836 proto_tree_add_text(att_tree, tvb, offset, 1,
1837 "..%d. = Expense metric: %s", ISIS_LSP_ATT_EXPENSE(lsp_att), ISIS_LSP_ATT_EXPENSE(lsp_att) ? "Set" : "Unset");
1838 proto_tree_add_text(att_tree, tvb, offset, 1,
1839 "...%d = Error metric: %s", ISIS_LSP_ATT_ERROR(lsp_att), ISIS_LSP_ATT_ERROR(lsp_att) ? "Set" : "Unset");
1840 proto_tree_add_boolean(info_tree, hf_isis_lsp_hippity, tvb, offset, 1, lsp_info);
1841 proto_tree_add_uint(info_tree, hf_isis_lsp_is_type, tvb, offset, 1, lsp_info);
1845 len = pdu_length - header_length;
1847 isis_dissect_unknown(tvb, tree, offset,
1848 "packet header length %d went beyond packet",
1853 * Now, we need to decode our CLVs. We need to pass in
1854 * our list of valid ones!
1856 if (lsp_type == ISIS_TYPE_L1_LSP){
1857 isis_dissect_clvs(tvb, lsp_tree, offset,
1858 clv_l1_lsp_opts, len, id_length,
1859 ett_isis_lsp_clv_unknown );
1861 isis_dissect_clvs(tvb, lsp_tree, offset,
1862 clv_l2_lsp_opts, len, id_length,
1863 ett_isis_lsp_clv_unknown );
1867 * Name: isis_register_lsp()
1870 * Register our protocol sub-sets with protocol manager.
1873 * int : protocol index for the ISIS protocol
1879 isis_register_lsp(int proto_isis) {
1880 static hf_register_info hf[] = {
1881 { &hf_isis_lsp_pdu_length,
1882 { "PDU length", "isis.lsp.pdu_length", FT_UINT16,
1883 BASE_DEC, NULL, 0x0, "", HFILL }},
1885 { &hf_isis_lsp_remaining_life,
1886 { "Remaining lifetime", "isis.lsp.remaining_life", FT_UINT16,
1887 BASE_DEC, NULL, 0x0, "", HFILL }},
1889 { &hf_isis_lsp_sequence_number,
1890 { "Sequence number", "isis.lsp.sequence_number",
1891 FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1893 { &hf_isis_lsp_checksum,
1894 { "Checksum", "isis.lsp.checksum",FT_UINT16,
1895 BASE_HEX, NULL, 0x0, "", HFILL }},
1897 { &hf_isis_lsp_clv_ipv4_int_addr,
1898 { "IPv4 interface address", "isis.lsp.clv_ipv4_int_addr", FT_IPv4,
1899 BASE_NONE, NULL, 0x0, "", HFILL }},
1901 { &hf_isis_lsp_clv_ipv6_int_addr,
1902 { "IPv6 interface address", "isis.lsp.clv_ipv6_int_addr", FT_IPv6,
1903 BASE_NONE, NULL, 0x0, "", HFILL }},
1905 { &hf_isis_lsp_clv_te_router_id,
1906 { "Traffic Engineering Router ID", "isis.lsp.clv_te_router_id", FT_IPv4,
1907 BASE_NONE, NULL, 0x0, "", HFILL }},
1909 { &hf_isis_lsp_clv_mt,
1910 { "MT-ID ", "isis.lsp.clv_mt",
1911 FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
1914 { "Partition Repair", "isis.lsp.partition_repair", FT_BOOLEAN, 8,
1915 TFS(&supported_string), ISIS_LSP_PARTITION_MASK,
1916 "If set, this router supports the optional Partition Repair function", HFILL }},
1919 { "Attachment", "isis.lsp.att", FT_UINT8, BASE_DEC,
1920 NULL, ISIS_LSP_ATT_MASK,
1923 { &hf_isis_lsp_hippity,
1924 { "Overload bit", "isis.lsp.overload", FT_BOOLEAN, 8,
1925 TFS(&hippity_string), ISIS_LSP_HIPPITY_MASK,
1926 "If set, this router will not be used by any decision process to calculate routes", HFILL }},
1928 { &hf_isis_lsp_is_type,
1929 { "Type of Intermediate System", "isis.lsp.is_type", FT_UINT8, BASE_DEC,
1930 VALS(isis_lsp_istype_vals), ISIS_LSP_IS_TYPE_MASK,
1933 static gint *ett[] = {
1937 &ett_isis_lsp_clv_area_addr,
1938 &ett_isis_lsp_clv_is_neighbors,
1939 &ett_isis_lsp_clv_ext_is_reachability, /* CLV 22 */
1940 &ett_isis_lsp_part_of_clv_ext_is_reachability,
1941 &ett_isis_lsp_subclv_admin_group,
1942 &ett_isis_lsp_subclv_unrsv_bw,
1943 &ett_isis_lsp_clv_unknown,
1944 &ett_isis_lsp_clv_partition_dis,
1945 &ett_isis_lsp_clv_prefix_neighbors,
1946 &ett_isis_lsp_clv_auth,
1947 &ett_isis_lsp_clv_nlpid,
1948 &ett_isis_lsp_clv_hostname,
1949 &ett_isis_lsp_clv_ipv4_int_addr,
1950 &ett_isis_lsp_clv_ipv6_int_addr, /* CLV 232 */
1951 &ett_isis_lsp_clv_te_router_id,
1952 &ett_isis_lsp_clv_ip_reachability,
1953 &ett_isis_lsp_clv_ip_reach_subclv,
1954 &ett_isis_lsp_clv_ext_ip_reachability, /* CLV 135 */
1955 &ett_isis_lsp_part_of_clv_ext_ip_reachability,
1956 &ett_isis_lsp_clv_ipv6_reachability, /* CLV 236 */
1957 &ett_isis_lsp_part_of_clv_ipv6_reachability,
1958 &ett_isis_lsp_clv_mt,
1959 &ett_isis_lsp_clv_mt_is,
1960 &ett_isis_lsp_part_of_clv_mt_is,
1961 &ett_isis_lsp_clv_mt_reachable_IPv4_prefx,
1962 &ett_isis_lsp_clv_mt_reachable_IPv6_prefx,
1965 proto_register_field_array(proto_isis, hf, array_length(hf));
1966 proto_register_subtree_array(ett, array_length(ett));