2 * Routines for decoding isis lsp packets and their CLVs
4 * $Id: packet-isis-lsp.c,v 1.21 2001/11/26 04:52:50 hagbard 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.
32 #ifdef HAVE_SYS_TYPES_H
33 # include <sys/types.h>
40 #ifdef HAVE_NET_INET_H
44 #include "epan/ipv4.h"
46 #include "packet-osi.h"
47 #include "packet-ipv6.h"
48 #include "packet-isis.h"
49 #include "packet-isis-clv.h"
50 #include "packet-isis-lsp.h"
54 static int proto_isis_lsp = -1;
55 static int hf_isis_lsp_pdu_length = -1;
56 static int hf_isis_lsp_remaining_life = -1;
57 static int hf_isis_lsp_sequence_number = -1;
58 static int hf_isis_lsp_checksum = -1;
59 static int hf_isis_lsp_clv_ipv4_int_addr = -1;
60 static int hf_isis_lsp_clv_ipv6_int_addr = -1;
61 static int hf_isis_lsp_clv_te_router_id = -1;
62 static int hf_isis_lsp_clv_mt = -1;
64 static gint ett_isis_lsp = -1;
65 static gint ett_isis_lsp_clv_area_addr = -1;
66 static gint ett_isis_lsp_clv_is_neighbors = -1;
67 static gint ett_isis_lsp_clv_ext_is_reachability = -1; /* CLV 22 */
68 static gint ett_isis_lsp_part_of_clv_ext_is_reachability = -1;
69 static gint ett_isis_lsp_subclv_admin_group = -1;
70 static gint ett_isis_lsp_subclv_unrsv_bw = -1;
71 static gint ett_isis_lsp_clv_unknown = -1;
72 static gint ett_isis_lsp_clv_partition_dis = -1;
73 static gint ett_isis_lsp_clv_prefix_neighbors = -1;
74 static gint ett_isis_lsp_clv_nlpid = -1;
75 static gint ett_isis_lsp_clv_hostname = -1;
76 static gint ett_isis_lsp_clv_te_router_id = -1;
77 static gint ett_isis_lsp_clv_auth = -1;
78 static gint ett_isis_lsp_clv_ipv4_int_addr = -1;
79 static gint ett_isis_lsp_clv_ipv6_int_addr = -1; /* CLV 232 */
80 static gint ett_isis_lsp_clv_ip_reachability = -1;
81 static gint ett_isis_lsp_clv_ext_ip_reachability = -1; /* CLV 135 */
82 static gint ett_isis_lsp_part_of_clv_ext_ip_reachability = -1;
83 static gint ett_isis_lsp_clv_ipv6_reachability = -1; /* CLV 236 */
84 static gint ett_isis_lsp_part_of_clv_ipv6_reachability = -1;
85 static gint ett_isis_lsp_clv_mt = -1;
86 static gint ett_isis_lsp_clv_mt_is = -1;
87 static gint ett_isis_lsp_part_of_clv_mt_is = -1;
89 static dissector_handle_t data_handle;
91 static const char *isis_lsp_attached_bits[] = {
92 "error", "expense", "delay", "default" };
94 static const value_string isis_lsp_istype_vals[] = {
95 { ISIS_LSP_TYPE_UNUSED0, "Unused 0x0 (invalid)"},
96 { ISIS_LSP_TYPE_LEVEL_1, "Level 1 IS"},
97 { ISIS_LSP_TYPE_UNUSED2, "Unused 0x2 (invalid)"},
98 { ISIS_LSP_TYPE_LEVEL_2, "Level 2 IS"},
102 * Predclare dissectors for use in clv dissection.
104 static void dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb,
105 packet_info *pinfo, proto_tree *tree, int offset,
106 int id_length, int length);
107 static void dissect_lsp_partition_dis_clv(tvbuff_t *tvb,
108 packet_info *pinfo, proto_tree *tree, int offset,
109 int id_length, int length);
110 static void dissect_lsp_mt_is_reachability_clv(tvbuff_t *tvb,
111 packet_info *pinfo, proto_tree *tree, int offset,
112 int id_length, int length);
113 static void dissect_lsp_ext_is_reachability_clv(tvbuff_t *tvb,
114 packet_info *pinfo, proto_tree *tree, int offset,
115 int id_length, int length);
116 static void dissect_lsp_l2_is_neighbors_clv(tvbuff_t *tvb,
117 packet_info *pinfo, proto_tree *tree, int offset,
118 int id_length, int length);
119 static void dissect_lsp_l1_es_neighbors_clv(tvbuff_t *tvb,
120 packet_info *pinfo, proto_tree *tree, int offset,
121 int id_length, int length);
122 static void dissect_lsp_l1_is_neighbors_clv(tvbuff_t *tvb,
123 packet_info *pinfo, proto_tree *tree, int offset,
124 int id_length, int length);
125 static void dissect_lsp_area_address_clv(tvbuff_t *tvb,
126 packet_info *pinfo, proto_tree *tree, int offset,
127 int id_length, int length);
128 static void dissect_lsp_l2_auth_clv(tvbuff_t *tvb,
129 packet_info *pinfo, proto_tree *tree, int offset,
130 int id_length, int length);
131 static void dissect_lsp_l1_auth_clv(tvbuff_t *tvb,
132 packet_info *pinfo, proto_tree *tree, int offset,
133 int id_length, int length);
134 static void dissect_lsp_ipv6_int_addr_clv(tvbuff_t *tvb,
135 packet_info *pinfo, proto_tree *tree, int offset,
136 int id_length, int length);
137 static void dissect_lsp_ip_int_addr_clv(tvbuff_t *tvb,
138 packet_info *pinfo, proto_tree *tree, int offset,
139 int id_length, int length);
140 static void dissect_lsp_te_router_id_clv(tvbuff_t *tvb,
141 packet_info *pinfo, proto_tree *tree, int offset,
142 int id_length, int length);
143 static void dissect_lsp_hostname_clv(tvbuff_t *tvb,
144 packet_info *pinfo, proto_tree *tree, int offset,
145 int id_length, int length);
146 static void dissect_lsp_mt_clv(tvbuff_t *tvb,
147 packet_info *pinfo, proto_tree *tree, int offset,
148 int id_length, int length);
149 static void dissect_lsp_nlpid_clv(tvbuff_t *tvb,
150 packet_info *pinfo, proto_tree *tree, int offset,
151 int id_length, int length);
152 static void dissect_lsp_ipv6_reachability_clv(tvbuff_t *tvb,
153 packet_info *pinfo, proto_tree *tree, int offset,
154 int id_length, int length);
155 static void dissect_lsp_ext_ip_reachability_clv(tvbuff_t *tvb,
156 packet_info *pinfo, proto_tree *tree, int offset,
157 int id_length, int length);
158 static void dissect_lsp_ip_reachability_clv(tvbuff_t *tvb,
159 packet_info *pinfo, proto_tree *tree, int offset,
160 int id_length, int length);
164 static const isis_clv_handle_t clv_l1_lsp_opts[] = {
166 ISIS_CLV_L1_LSP_AREA_ADDRESS,
168 &ett_isis_lsp_clv_area_addr,
169 dissect_lsp_area_address_clv
172 ISIS_CLV_L1_LSP_IS_NEIGHBORS,
174 &ett_isis_lsp_clv_is_neighbors,
175 dissect_lsp_l1_is_neighbors_clv
178 ISIS_CLV_L1_LSP_ES_NEIGHBORS,
180 &ett_isis_lsp_clv_is_neighbors,
181 dissect_lsp_l1_es_neighbors_clv
184 ISIS_CLV_L1_LSP_EXT_IS_REACHABLE,
185 "Extended IS reachability",
186 &ett_isis_lsp_clv_ext_is_reachability,
187 dissect_lsp_ext_is_reachability_clv
190 ISIS_CLV_L1_LSP_IP_INT_REACHABLE,
191 "IP Internal reachability",
192 &ett_isis_lsp_clv_ip_reachability,
193 dissect_lsp_ip_reachability_clv
196 ISIS_CLV_L1_LSP_IP_EXT_REACHABLE,
197 "IP External reachability",
198 &ett_isis_lsp_clv_ip_reachability,
199 dissect_lsp_ip_reachability_clv
202 ISIS_CLV_L1_LSP_EXT_IP_REACHABLE,
203 "Extended IP Reachability",
204 &ett_isis_lsp_clv_ext_ip_reachability,
205 dissect_lsp_ext_ip_reachability_clv
208 ISIS_CLV_L1_LSP_IPv6_REACHABLE,
210 &ett_isis_lsp_clv_ipv6_reachability,
211 dissect_lsp_ipv6_reachability_clv
214 ISIS_CLV_L1_LSP_NLPID,
215 "Protocols supported",
216 &ett_isis_lsp_clv_nlpid,
217 dissect_lsp_nlpid_clv
220 ISIS_CLV_L1_LSP_HOSTNAME,
222 &ett_isis_lsp_clv_hostname,
223 dissect_lsp_hostname_clv
226 ISIS_CLV_L1_LSP_TE_ROUTER_ID,
227 "Traffic Engineering Router ID",
228 &ett_isis_lsp_clv_te_router_id,
229 dissect_lsp_te_router_id_clv
232 ISIS_CLV_L1_LSP_IP_INTERFACE_ADDR,
233 "IP Interface address(es)",
234 &ett_isis_lsp_clv_ipv4_int_addr,
235 dissect_lsp_ip_int_addr_clv
238 ISIS_CLV_L1_LSP_IPv6_INTERFACE_ADDR,
239 "IPv6 Interface address(es)",
240 &ett_isis_lsp_clv_ipv6_int_addr,
241 dissect_lsp_ipv6_int_addr_clv
244 ISIS_CLV_L1_LSP_AUTHENTICATION_NS,
245 "Authentication(non-spec)",
246 &ett_isis_lsp_clv_auth,
247 dissect_lsp_l1_auth_clv
250 ISIS_CLV_L1_LSP_AUTHENTICATION,
252 &ett_isis_lsp_clv_auth,
253 dissect_lsp_l1_auth_clv
258 &ett_isis_lsp_clv_mt,
262 ISIS_CLV_L1_LSP_MT_IS_REACHABLE,
263 "Multi Topology IS Reachability",
264 &ett_isis_lsp_clv_mt_is,
265 dissect_lsp_mt_is_reachability_clv
276 static const isis_clv_handle_t clv_l2_lsp_opts[] = {
278 ISIS_CLV_L1_LSP_AREA_ADDRESS,
280 &ett_isis_lsp_clv_area_addr,
281 dissect_lsp_area_address_clv
284 ISIS_CLV_L2_LSP_IS_NEIGHBORS,
286 &ett_isis_lsp_clv_is_neighbors,
287 dissect_lsp_l2_is_neighbors_clv
290 ISIS_CLV_L2_LSP_EXT_IS_REACHABLE,
291 "Extended IS reachability",
292 &ett_isis_lsp_clv_ext_is_reachability,
293 dissect_lsp_ext_is_reachability_clv
296 ISIS_CLV_L2_LSP_PARTITION_DIS,
297 "Parition Designated Level 2 IS",
298 &ett_isis_lsp_clv_partition_dis,
299 dissect_lsp_partition_dis_clv
302 ISIS_CLV_L2_LSP_PREFIX_NEIGHBORS,
304 &ett_isis_lsp_clv_prefix_neighbors,
305 dissect_lsp_prefix_neighbors_clv
308 ISIS_CLV_L2_LSP_IP_INT_REACHABLE,
309 "IP Internal reachability",
310 &ett_isis_lsp_clv_ip_reachability,
311 dissect_lsp_ip_reachability_clv
314 ISIS_CLV_L2_LSP_IP_EXT_REACHABLE,
315 "IP External reachability",
316 &ett_isis_lsp_clv_ip_reachability,
317 dissect_lsp_ip_reachability_clv
320 ISIS_CLV_L2_LSP_NLPID,
321 "Protocols supported",
322 &ett_isis_lsp_clv_nlpid,
323 dissect_lsp_nlpid_clv
326 ISIS_CLV_L2_LSP_HOSTNAME,
328 &ett_isis_lsp_clv_hostname,
329 dissect_lsp_hostname_clv
332 ISIS_CLV_L2_LSP_TE_ROUTER_ID,
333 "Traffic Engineering Router ID",
334 &ett_isis_lsp_clv_te_router_id,
335 dissect_lsp_te_router_id_clv
338 ISIS_CLV_L2_LSP_EXT_IP_REACHABLE,
339 "Extended IP Reachability",
340 &ett_isis_lsp_clv_ext_ip_reachability,
341 dissect_lsp_ext_ip_reachability_clv
344 ISIS_CLV_L2_LSP_IPv6_REACHABLE,
346 &ett_isis_lsp_clv_ipv6_reachability,
347 dissect_lsp_ipv6_reachability_clv
350 ISIS_CLV_L2_LSP_IP_INTERFACE_ADDR,
351 "IP Interface address(es)",
352 &ett_isis_lsp_clv_ipv4_int_addr,
353 dissect_lsp_ip_int_addr_clv
356 ISIS_CLV_L2_LSP_IPv6_INTERFACE_ADDR,
357 "IPv6 Interface address(es)",
358 &ett_isis_lsp_clv_ipv6_int_addr,
359 dissect_lsp_ipv6_int_addr_clv
362 ISIS_CLV_L2_LSP_AUTHENTICATION_NS,
363 "Authentication(non spec)",
364 &ett_isis_lsp_clv_auth,
365 dissect_lsp_l2_auth_clv
368 ISIS_CLV_L2_LSP_AUTHENTICATION,
370 &ett_isis_lsp_clv_auth,
371 dissect_lsp_l2_auth_clv
376 &ett_isis_lsp_clv_mt,
380 ISIS_CLV_L2_LSP_MT_IS_REACHABLE,
381 "Multi Topology IS Reachability",
382 &ett_isis_lsp_clv_mt_is,
383 dissect_lsp_mt_is_reachability_clv
395 * Name: dissect_metric()
398 * Display a metric prefix portion. ISIS has the concept of multple
399 * metric per prefix (default, delay, expense, and error). This
400 * routine assists other dissectors by adding a single one of
401 * these to the display tree..
403 * The 8th(msbit) bit in the metric octet is the "supported" bit. The
404 * "default" support is required, so we support a "force_supported"
405 * flag that tells us that it MUST be zero (zero==supported,
406 * so it really should be a "not supported" in the boolean sense)
407 * and to display a protocol failure accordingly. Notably,
408 * Cisco IOS 12(6) blows this!
409 * The 7th bit must be zero (reserved).
412 * tvbuff_t * : tvbuffer for packet data
413 * packet_info * : info for current packet
414 * proto_tree * : protocol display tree to fill out. May be NULL
415 * int : offset into packet data where we are.
416 * guint8 : value of the metric.
417 * char * : string giving type of the metric.
418 * int : force supported. True is the supported bit MUST be zero.
421 * void, but we will add to proto tree if !NULL.
424 dissect_metric(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
425 int offset, guint8 value, char *pstr, int force_supported )
431 s = ISIS_LSP_CLV_METRIC_SUPPORTED(value);
432 proto_tree_add_text(tree, tvb, offset, 1,
433 "%s Metric: %s%s %s%d:%d", pstr,
434 s ? "Not supported" : "Supported",
435 (s && force_supported) ? "(but is required to be)":"",
436 ISIS_LSP_CLV_METRIC_RESERVED(value) ? "(reserved bit != 0)":"",
437 ISIS_LSP_CLV_METRIC_VALUE(value), value );
441 * Name: dissect_lsp_ip_reachability_clv()
444 * Decode an IP reachability CLV. This can be either internal or
445 * external (the clv format does not change and which type we are
446 * displaying is put there by the dispatcher). All of these
447 * are a metric block followed by an IP addr and mask.
450 * tvbuff_t * : tvbuffer for packet data
451 * packet_info * : info for current packet
452 * proto_tree * : proto tree to build on (may be null)
453 * int : current offset into packet data
454 * int : length of IDs in packet.
455 * int : length of this clv
458 * void, will modify proto_tree if not null.
461 dissect_lsp_ip_reachability_clv(tvbuff_t *tvb,
462 packet_info *pinfo, proto_tree *tree, int offset,
463 int id_length, int length)
466 proto_tree *ntree = NULL;
467 guint32 src, mask, prefix_len;
469 guint32 bitmasks[33] = {
471 0x00000008, 0x0000000c, 0x0000000e, 0x0000000f,
472 0x000000f8, 0x000000fc, 0x000000fe, 0x000000ff,
473 0x000008ff, 0x00000cff, 0x00000eff, 0x00000fff,
474 0x0000f8ff, 0x0000fcff, 0x0000feff, 0x0000ffff,
475 0x0008ffff, 0x000cffff, 0x000effff, 0x000fffff,
476 0x00f8ffff, 0x00fcffff, 0x00feffff, 0x00ffffff,
477 0x08ffffff, 0x0cffffff, 0x0effffff, 0x0fffffff,
478 0xf8ffffff, 0xfcffffff, 0xfeffffff, 0xffffffff
482 while ( length > 0 ) {
484 isis_dissect_unknown(tvb, pinfo, tree, offset,
485 "short IP reachability (%d vs 12)", length );
489 * Gotta build a sub-tree for all our pieces
492 tvb_memcpy(tvb, (guint8 *)&src, offset+4, 4);
493 tvb_memcpy(tvb, (guint8 *)&mask, offset+8, 4);
495 /* find out if the mask matches one of 33 possible prefix lengths */
499 while(prefix_len<=33) {
500 if (bitmasks[prefix_len++]==mask) {
506 /* 34 indicates no match -> must be a discontiguous netmask
507 lets dump the mask, otherwise print the prefix_len */
510 ti = proto_tree_add_text ( tree, tvb, offset, 12,
511 "IPv4 prefix: %s mask %s",
512 ip_to_str((guint8*)&src),
513 ip_to_str((guint8*)&mask));
515 ti = proto_tree_add_text ( tree, tvb, offset, 12,
516 "IPv4 prefix: %s/%d",
517 ip_to_str((guint8*)&src),
521 ntree = proto_item_add_subtree(ti,
522 ett_isis_lsp_clv_ip_reachability);
524 proto_tree_add_text (ntree, tvb, offset, 1,
525 "Default Metric: %d, %s, Distribution: %s",
526 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset)),
527 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset)) ? "External" : "Internal",
528 ISIS_LSP_CLV_METRIC_UPDOWN(tvb_get_guint8(tvb, offset)) ? "down" : "up");
531 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+1))) {
532 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: Not supported");
534 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: %d, %s",
535 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+1)),
536 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+1)) ? "External" : "Internal");
539 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+2))) {
540 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: Not supported");
542 proto_tree_add_text (ntree, tvb, offset+2, 1, "Exense Metric: %d, %s",
543 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+2)),
544 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+2)) ? "External" : "Internal");
547 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+3))) {
548 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: Not supported");
550 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: %d, %s",
551 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+3)),
552 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+3)) ? "External" : "Internal");
561 * Name: dissect_lsp_ext_ip_reachability_clv()
563 * Description: Decode an Extended IP Reachability CLV - code 135.
565 * The extended IP reachability TLV is an extended version
566 * of the IP reachability TLVs (codes 128 and 130). It encodes
567 * the metric as a 32-bit unsigned interger and allows to add
571 * tvbuff_t * : tvbuffer for packet data
572 * packet_info * : info for current packet
573 * proto_tree * : proto tree to build on (may be null)
574 * int : current offset into packet data
575 * int : length of IDs in packet.
576 * int : length of this clv
579 * void, will modify proto_tree if not null.
582 dissect_lsp_ext_ip_reachability_clv(tvbuff_t *tvb,
583 packet_info *pinfo, proto_tree *tree, int offset,
584 int id_length, int length)
586 proto_item *pi = NULL;
587 proto_tree *subtree = NULL;
589 guint8 bit_length, byte_length;
596 memset (prefix, 0, 4);
597 ctrl_info = tvb_get_guint8(tvb, offset+4);
598 bit_length = ctrl_info & 0x3f;
599 byte_length = (bit_length + 7) / 8;
600 tvb_memcpy (tvb, prefix, offset+5, byte_length);
601 pi = proto_tree_add_text (tree, tvb, offset, 0,
602 "IPv4 prefix: %s/%d",
605 subtree = proto_item_add_subtree (pi,
606 ett_isis_lsp_part_of_clv_ext_ip_reachability);
608 proto_tree_add_text (subtree, tvb, offset, 4,
609 "Metric: %d, Distribution: %s", tvb_get_ntohl(tvb, offset), ((ctrl_info & 0x80) == 0) ? "up" : "down" );
611 proto_tree_add_text (subtree, tvb, offset+4, 1,
612 "%s sub-TLVs present",
613 ((ctrl_info & 0x40) == 0) ? "no" : "" );
615 len = 5 + byte_length;
616 if ((ctrl_info & 0x40) != 0)
617 len += 1 + tvb_get_guint8(tvb, offset+len) ;
618 proto_item_set_len (pi, len);
625 * Name: dissect_lsp_ipv6_reachability_clv()
627 * Description: Decode an IPv6 reachability CLV - code 236.
630 * tvbuff_t * : tvbuffer for packet data
631 * packet_info * : info for current packet
632 * proto_tree * : proto tree to build on (may be null)
633 * int : current offset into packet data
634 * int : length of IDs in packet.
635 * int : length of this clv
638 * void, will modify proto_tree if not null.
641 dissect_lsp_ipv6_reachability_clv(tvbuff_t *tvb,
642 packet_info *pinfo, proto_tree *tree, int offset,
643 int id_length, int length)
646 proto_tree *ntree = NULL;
647 guint8 bit_length, byte_length;
648 struct e_in6_addr prefix;
655 memset (prefix.s6_addr, 0, 16);
658 bit_length = tvb_get_guint8(tvb, offset+5);
659 byte_length = (bit_length + 7) / 8;
660 tvb_memcpy (tvb, prefix.s6_addr, offset+6, byte_length);
661 ti = proto_tree_add_text (tree, tvb, offset, 0,
663 ip6_to_str (&prefix),
665 ntree = proto_item_add_subtree (ti, ett_isis_lsp_part_of_clv_ipv6_reachability);
667 metric = tvb_get_ntohl(tvb, offset);
668 proto_tree_add_text (ntree, tvb, offset, 4,
669 "Metric: %d", metric);
671 ctrl_info = tvb_get_guint8(tvb, offset+4);
672 proto_tree_add_text (ntree, tvb, offset+4, 1,
673 "Distribution: %s, %s",
674 ((ctrl_info & 0x80) == 0) ? "up" : "down",
675 ((ctrl_info & 0x40) == 0) ? "internal" : "external" );
677 proto_tree_add_text (ntree, tvb, offset+4, 1,
678 "Reserved bits: 0x%x",
679 (ctrl_info & 0x1f) );
680 proto_tree_add_text (ntree, tvb, offset+4, 1,
682 ((ctrl_info & 0x20) == 0) ? "no" : "yes" );
684 len = 6 + byte_length;
685 if ((ctrl_info & 0x20) != 0)
686 len += 1 + tvb_get_guint8(tvb, offset+len);
687 proto_item_set_len (ti, len);
694 * Name: dissect_lsp_nlpid_clv()
697 * Decode for a lsp packets NLPID clv. Calls into the
701 * tvbuff_t * : tvbuffer for packet data
702 * packet_info * : info for current packet
703 * proto_tree * : proto tree to build on (may be null)
704 * int : current offset into packet data
705 * int : length of IDs in packet.
706 * int : length of this clv
709 * void, will modify proto_tree if not null.
712 dissect_lsp_nlpid_clv(tvbuff_t *tvb,
713 packet_info *pinfo, proto_tree *tree, int offset,
714 int id_length, int length)
716 isis_dissect_nlpid_clv(tvb, pinfo, tree, offset, length);
720 * Name: dissect_lsp_mt_clv()
723 * Decode for a lsp packets Multi Topology clv. Calls into the
727 * u_char * : packet data
728 * int : current offset into packet data
729 * guint : length of this clv
730 * int : length of IDs in packet.
731 * frame_data * : frame data
732 * proto_tree * : proto tree to build on (may be null)
735 * void, will modify proto_tree if not null.
738 dissect_lsp_mt_clv(tvbuff_t *tvb,
739 packet_info *pinfo, proto_tree *tree, int offset,
740 int id_length, int length)
742 isis_dissect_mt_clv(tvb, pinfo, tree, offset, length,
743 hf_isis_lsp_clv_mt );
747 * Name: dissect_lsp_hostname_clv()
750 * Decode for a lsp packets hostname clv. Calls into the
754 * tvbuff_t * : tvbuffer for packet data
755 * packet_info * : info for current packet
756 * proto_tree * : proto tree to build on (may be null)
757 * int : current offset into packet data
758 * int : length of IDs in packet.
759 * int : length of this clv
762 * void, will modify proto_tree if not null.
765 dissect_lsp_hostname_clv(tvbuff_t *tvb,
766 packet_info *pinfo, proto_tree *tree, int offset,
767 int id_length, int length)
769 isis_dissect_hostname_clv(tvb, pinfo, tree, offset, length);
774 * Name: dissect_lsp_te_router_id_clv()
777 * Decode for a lsp packets Traffic Engineering ID clv. Calls into the
781 * tvbuff_t * : tvbuffer for packet data
782 * packet_info * : info for current packet
783 * proto_tree * : proto tree to build on (may be null)
784 * int : current offset into packet data
785 * int : length of IDs in packet.
786 * int : length of this clv
789 * void, will modify proto_tree if not null.
792 dissect_lsp_te_router_id_clv(tvbuff_t *tvb,
793 packet_info *pinfo, proto_tree *tree, int offset,
794 int id_length, int length)
796 isis_dissect_te_router_id_clv(tvb, pinfo, tree, offset, length,
797 hf_isis_lsp_clv_te_router_id );
802 * Name: dissect_lsp_ip_int_addr_clv()
805 * Decode for a lsp packets ip interface addr clv. Calls into the
809 * tvbuff_t * : tvbuffer for packet data
810 * packet_info * : info for current packet
811 * proto_tree * : proto tree to build on (may be null)
812 * int : current offset into packet data
813 * int : length of IDs in packet.
814 * int : length of this clv
817 * void, will modify proto_tree if not null.
820 dissect_lsp_ip_int_addr_clv(tvbuff_t *tvb,
821 packet_info *pinfo, proto_tree *tree, int offset,
822 int id_length, int length)
824 isis_dissect_ip_int_clv(tvb, pinfo, tree, offset, length,
825 hf_isis_lsp_clv_ipv4_int_addr );
829 * Name: dissect_lsp_ipv6_int_addr_clv()
831 * Description: Decode an IPv6 interface addr CLV - code 232.
833 * Calls into the clv common one.
836 * tvbuff_t * : tvbuffer for packet data
837 * packet_info * : info for current packet
838 * proto_tree * : proto tree to build on (may be null)
839 * int : current offset into packet data
840 * int : length of IDs in packet.
841 * int : length of this clv
844 * void, will modify proto_tree if not null.
847 dissect_lsp_ipv6_int_addr_clv(tvbuff_t *tvb,
848 packet_info *pinfo, proto_tree *tree, int offset,
849 int id_length, int length)
851 isis_dissect_ipv6_int_clv(tvb, pinfo, tree, offset, length,
852 hf_isis_lsp_clv_ipv6_int_addr );
856 * Name: dissect_lsp_L1_auth_clv()
859 * Decode for a lsp packets authenticaion clv. Calls into the
860 * clv common one. An auth inside a L1 LSP is a per area password
863 * tvbuff_t * : tvbuffer for packet data
864 * packet_info * : info for current packet
865 * proto_tree * : proto tree to build on (may be null)
866 * int : current offset into packet data
867 * int : length of IDs in packet.
868 * int : length of this clv
871 * void, will modify proto_tree if not null.
874 dissect_lsp_l1_auth_clv(tvbuff_t *tvb,
875 packet_info *pinfo, proto_tree *tree, int offset,
876 int id_length, int length)
878 isis_dissect_authentication_clv(tvb, pinfo, tree, offset, length,
879 "Per area authentication" );
883 * Name: dissect_lsp_L2_auth_clv()
886 * Decode for a lsp packets authenticaion clv. Calls into the
887 * clv common one. An auth inside a L2 LSP is a per domain password
890 * tvbuff_t * : tvbuffer for packet data
891 * packet_info * : info for current packet
892 * proto_tree * : proto tree to build on (may be null)
893 * int : current offset into packet data
894 * int : length of IDs in packet.
895 * int : length of this clv
898 * void, will modify proto_tree if not null.
901 dissect_lsp_l2_auth_clv(tvbuff_t *tvb,
902 packet_info *pinfo, proto_tree *tree, int offset,
903 int id_length, int length)
905 isis_dissect_authentication_clv(tvb, pinfo, tree, offset, length,
906 "Per domain authentication" );
910 * Name: dissect_lsp_area_address_clv()
913 * Decode for a lsp packet's area address clv. Call into clv common
917 * tvbuff_t * : tvbuffer for packet data
918 * packet_info * : info for current packet
919 * proto_tree * : protocol display tree to fill out. May be NULL
920 * int : offset into packet data where we are.
921 * int : length of IDs in packet.
922 * int : length of clv we are decoding
925 * void, but we will add to proto tree if !NULL.
928 dissect_lsp_area_address_clv(tvbuff_t *tvb,
929 packet_info *pinfo, proto_tree *tree, int offset,
930 int id_length, int length)
932 isis_dissect_area_address_clv(tvb, pinfo, tree, offset, length);
936 * Name: dissect_lsp_eis_neighbors_clv_inner()
939 * Real work horse for showing neighbors. This means we decode the
940 * first octet as either virtual/!virtual (if show_virtual param is
941 * set), or as a must == 0 reserved value.
943 * Once past that, we decode n neighbor elements. Each neighbor
944 * is comprised of a metric block (is dissect_metric) and the
948 * tvbuff_t * : tvbuffer for packet data
949 * packet_info * : info for current packet
950 * proto_tree * : protocol display tree to fill out. May be NULL
951 * int : offset into packet data where we are.
952 * int : length of IDs in packet.
953 * int : length of clv we are decoding
954 * int : set to decode first octet as virtual vs reserved == 0
955 * int : set to indicate EIS instead of IS (6 octet per addr instead of 7)
958 * void, but we will add to proto tree if !NULL.
961 dissect_lsp_eis_neighbors_clv_inner(tvbuff_t *tvb, packet_info *pinfo,
962 proto_tree *tree, int offset,
963 int length, int id_length, int show_virtual, int is_eis)
966 proto_tree *ntree = NULL;
970 id_length++; /* IDs are one octet longer in IS neighbours */
972 if ( show_virtual ) {
973 /* virtual path flag */
974 proto_tree_add_text ( tree, tvb, offset, 1,
975 tvb_get_guint8(tvb, offset) ? "IsNotVirtual" : "IsVirtual" );
977 proto_tree_add_text ( tree, tvb, offset, 1,
978 "Reserved value 0x%02x, must == 0",
979 tvb_get_guint8(tvb, offset) );
985 tlen = 4 + id_length;
987 while ( length > 0 ) {
989 isis_dissect_unknown(tvb, pinfo, tree, offset,
990 "short E/IS reachability (%d vs %d)", length,
995 * Gotta build a sub-tree for all our pieces
999 ti = proto_tree_add_text(tree, tvb, offset, tlen,
1001 print_system_id( tvb_get_ptr(tvb, offset+4, id_length), id_length ) );
1003 ti = proto_tree_add_text(tree, tvb, offset, tlen,
1005 print_system_id(tvb_get_ptr(tvb, offset+4, id_length), id_length ) );
1007 ntree = proto_item_add_subtree(ti,
1008 ett_isis_lsp_clv_is_neighbors);
1012 proto_tree_add_text (ntree, tvb, offset, 1,
1013 "Default Metric: %d, %s",
1014 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset)),
1015 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset)) ? "External" : "Internal");
1017 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+1))) {
1018 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: Not supported");
1020 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: %d, %s",
1021 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+1)),
1022 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+1)) ? "External" : "Internal");
1026 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+2))) {
1027 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: Not supported");
1029 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: %d, %s",
1030 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+2)),
1031 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+2)) ? "External" : "Internal");
1034 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+3))) {
1035 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: Not supported");
1037 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: %d, %s",
1038 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+3)),
1039 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+3)) ? "External" : "Internal");
1049 * Name: dissect_lsp_l1_is_neighbors_clv()
1052 * Dispatch a l1 intermediate system neighbor by calling
1053 * the inner function with show virtual set to TRUE and is es set to FALSE.
1056 * tvbuff_t * : tvbuffer for packet data
1057 * packet_info * : info for current packet
1058 * proto_tree * : protocol display tree to fill out. May be NULL
1059 * int : offset into packet data where we are.
1060 * int : length of IDs in packet.
1061 * int : length of clv we are decoding
1064 * void, but we will add to proto tree if !NULL.
1067 dissect_lsp_l1_is_neighbors_clv(tvbuff_t *tvb,
1068 packet_info *pinfo, proto_tree *tree, int offset,
1069 int id_length, int length)
1071 dissect_lsp_eis_neighbors_clv_inner(tvb, pinfo, tree, offset,
1072 length, id_length, TRUE, FALSE);
1076 * Name: dissect_lsp_l1_es_neighbors_clv()
1079 * Dispatch a l1 end or intermediate system neighbor by calling
1080 * the inner function with show virtual set to TRUE and es set to TRUE.
1083 * tvbuff_t * : tvbuffer for packet data
1084 * packet_info * : info for current packet
1085 * proto_tree * : protocol display tree to fill out. May be NULL
1086 * int : offset into packet data where we are.
1087 * int : length of IDs in packet.
1088 * int : length of clv we are decoding
1091 * void, but we will add to proto tree if !NULL.
1094 dissect_lsp_l1_es_neighbors_clv(tvbuff_t *tvb,
1095 packet_info *pinfo, proto_tree *tree, int offset,
1096 int id_length, int length)
1098 dissect_lsp_eis_neighbors_clv_inner(tvb, pinfo, tree, offset,
1099 length, id_length, TRUE, TRUE);
1103 * Name: dissect_lsp_l2_is_neighbors_clv()
1106 * Dispatch a l2 intermediate system neighbor by calling
1107 * the inner function with show virtual set to FALSE, and is es set
1111 * tvbuff_t * : tvbuffer for packet data
1112 * packet_info * : info for current packet
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
1119 * void, but we will add to proto tree if !NULL.
1122 dissect_lsp_l2_is_neighbors_clv(tvbuff_t *tvb,
1123 packet_info *pinfo, proto_tree *tree, int offset,
1124 int id_length, int length)
1126 dissect_lsp_eis_neighbors_clv_inner(tvb, pinfo, tree, offset,
1127 length, id_length, FALSE, FALSE);
1132 * Name: dissect_subclv_admin_group ()
1134 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1136 * This function is called by dissect_lsp_ext_is_reachability_clv()
1137 * for dissect the administrive group sub-CLV (code 3).
1140 * tvbuff_t * : tvbuffer for packet data
1141 * packet_info * : info for current packet
1142 * proto_tree * : protocol display tree to fill out.
1143 * int : offset into packet data where we are (beginning of the sub_clv value).
1149 dissect_subclv_admin_group (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset) {
1156 ti = proto_tree_add_text(tree, tvb, offset-2, 6, "Administrative group(s):");
1157 ntree = proto_item_add_subtree (ti, ett_isis_lsp_subclv_admin_group);
1159 clv_value = tvb_get_ntohl(tvb, offset);
1161 for (i = 0 ; i < 32 ; i++) {
1162 if ( (clv_value & mask) != 0 ) {
1163 proto_tree_add_text (ntree, tvb, offset, 4, "group %d", i);
1170 * Name: dissect_subclv_max_bw ()
1172 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1174 * This function is called by dissect_lsp_ext_is_reachability_clv()
1175 * for dissect the maximum link bandwidth sub-CLV (code 9).
1178 * u_char * : packet data
1179 * int : offset into packet data where we are (beginning of the sub_clv value).
1180 * proto_tree * : protocol display tree to fill out.
1186 dissect_subclv_max_bw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1191 ui = tvb_get_ntohl(tvb, offset);
1192 memcpy (&bw, &ui, 4);
1193 proto_tree_add_text (tree, tvb, offset-2, 6,
1194 "Maximum link bandwidth : %.2f Mbps", bw*8/1000000 );
1198 * Name: dissect_subclv_rsv_bw ()
1200 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1202 * This function is called by dissect_lsp_ext_is_reachability_clv()
1203 * for dissect the reservable link bandwidth sub-CLV (code 10).
1206 * u_char * : packet data
1207 * int : offset into packet data where we are (beginning of the sub_clv value).
1208 * proto_tree * : protocol display tree to fill out.
1214 dissect_subclv_rsv_bw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1219 ui = tvb_get_ntohl(tvb, offset);
1220 memcpy (&bw, &ui, 4);
1221 proto_tree_add_text (tree, tvb, offset-2, 6,
1222 "Reservable link bandwidth: %.2f Mbps", bw*8/1000000 );
1226 * Name: dissect_subclv_unrsv_bw ()
1228 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1230 * This function is called by dissect_lsp_ext_is_reachability_clv()
1231 * for dissect the unreserved bandwidth sub-CLV (code 11).
1234 * u_char * : packet data
1235 * int : offset into packet data where we are (beginning of the sub_clv value).
1236 * proto_tree * : protocol display tree to fill out.
1242 dissect_subclv_unrsv_bw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1250 ti = proto_tree_add_text (tree, tvb, offset-2, 34, "Unreserved bandwidth:");
1251 ntree = proto_item_add_subtree (ti, ett_isis_lsp_subclv_unrsv_bw);
1253 for (i = 0 ; i < 8 ; i++) {
1254 ui = tvb_get_ntohl(tvb, offset);;
1255 memcpy (&bw, &ui, 4);
1256 proto_tree_add_text (ntree, tvb, offset+4*i, 4,
1257 "priority level %d: %.2f Mbps", i, bw*8/1000000 );
1262 * Name: dissect_lsp_ext_is_reachability_clv()
1264 * Description: Decode a Extended IS Reachability CLV - code 22
1266 * The extended IS reachability TLV is an extended version
1267 * of the IS reachability TLV (code 2). It encodes the metric
1268 * as a 24-bit unsigned interger and allows to add sub-CLV(s).
1271 * tvbuff_t * : tvbuffer for packet data
1272 * packet_info * : info for current packet
1273 * proto_tree * : protocol display tree to fill out. May be NULL
1274 * int : offset into packet data where we are.
1275 * int : length of IDs in packet.
1276 * int : length of clv we are decoding
1279 * void, but we will add to proto tree if !NULL.
1282 dissect_lsp_ext_is_reachability_clv(tvbuff_t *tvb,
1283 packet_info *pinfo, proto_tree *tree, int offset,
1284 int id_length, int length)
1287 proto_tree *ntree = NULL;
1290 guint8 clv_code, clv_len;
1294 while (length > 0) {
1295 ti = proto_tree_add_text (tree, tvb, offset, 0,
1297 print_system_id (tvb_get_ptr(tvb, offset, 7), 7) );
1298 ntree = proto_item_add_subtree (ti,
1299 ett_isis_lsp_part_of_clv_ext_is_reachability );
1301 proto_tree_add_text (ntree, tvb, offset+7, 3,
1302 "Metric: %d", tvb_get_ntoh24(tvb, offset+7) );
1304 subclvs_len = tvb_get_guint8(tvb, offset+10);
1305 if (subclvs_len == 0) {
1306 proto_tree_add_text (ntree, tvb, offset+10, 1, "no sub-TLVs present");
1310 while (i < subclvs_len) {
1311 clv_code = tvb_get_guint8(tvb, offset+11+i);
1312 clv_len = tvb_get_guint8(tvb, offset+12+i);
1315 dissect_subclv_admin_group(tvb, pinfo, ntree, offset+13+i);
1318 proto_tree_add_text (ntree, tvb, offset+11+i, 6,
1319 "IPv4 interface address: %s", ip_to_str (tvb_get_ptr(tvb, offset+13+i, 4)) );
1322 proto_tree_add_text (ntree, tvb, offset+11+i, 6,
1323 "IPv4 neighbor address: %s", ip_to_str (tvb_get_ptr(tvb, offset+13+i, 4)) );
1326 dissect_subclv_max_bw (tvb, pinfo, ntree, offset+13+i);
1329 dissect_subclv_rsv_bw (tvb, pinfo, ntree, offset+13+i);
1332 dissect_subclv_unrsv_bw (tvb, pinfo, ntree, offset+13+i);
1335 proto_tree_add_text (ntree, tvb, offset+11+i, 5,
1336 "Traffic engineering default metric: %d",
1337 tvb_get_ntoh24(tvb, offset+13+i) );
1344 proto_tree_add_text (ntree, tvb, offset+11+i, clv_len+2,
1345 "Unknown Cisco specific extensions: code %d, length %d",
1346 clv_code, clv_len );
1349 proto_tree_add_text (ntree, tvb, offset+11+i, clv_len+2,
1350 "Unknown sub-CLV: code %d, length %d", clv_code, clv_len );
1357 len = 11 + subclvs_len;
1358 proto_item_set_len (ti, len);
1369 static void dissect_lsp_mt_is_reachability_clv(tvbuff_t *tvb,
1370 packet_info *pinfo, proto_tree *tree, int offset,
1371 int id_length, int length)
1374 proto_tree *ntree = NULL;
1383 while (length > 0) {
1385 /* fetch two bytes */
1386 mt_block = tvb_get_ntohs(tvb, offset);
1388 /* mask out the lower 12 bits */
1389 switch(mt_block&0x0fff) {
1391 strcpy(mt_desc,"IPv4 unicast");
1394 strcpy(mt_desc,"In-Band Management");
1397 strcpy(mt_desc,"IPv6 unicast");
1400 strcpy(mt_desc,"Multicast");
1403 strcpy(mt_desc,"Development, Experimental or Proprietary");
1406 strcpy(mt_desc,"Reserved for IETF Consensus");
1409 proto_tree_add_text ( tree, tvb, offset, 2 ,
1410 "%s Topology (0x%x)",
1414 ti = proto_tree_add_text (tree, tvb, offset+2, 0,
1416 print_system_id(tvb_get_ptr(tvb, offset+2, 7), 7) );
1418 ntree = proto_item_add_subtree (ti,
1419 ett_isis_lsp_part_of_clv_mt_is );
1421 proto_tree_add_text (ntree, tvb, offset+9, 3,
1422 "Metric: %d", tvb_get_ntoh24(tvb, offset+9) );
1424 subclvs_len = tvb_get_guint8(tvb, offset+12);
1425 if (subclvs_len == 0) {
1426 proto_tree_add_text (ntree, tvb, offset+12, 1, "no sub-TLVs present");
1428 proto_tree_add_text (ntree, tvb, offset+12, 1, "sub-TLVs present");
1431 len = 13 + subclvs_len;
1432 proto_item_set_len (ti, len);
1440 * Name: dissect_lsp_partition_dis_clv()
1443 * This CLV is used to indicate which system is the designated
1444 * IS for partition repair. This means just putting out the
1445 * "id_length"-octet IS.
1448 * tvbuff_t * : tvbuffer for packet data
1449 * packet_info * : info for current packet
1450 * proto_tree * : protocol display tree to fill out. May be NULL
1451 * int : offset into packet data where we are.
1452 * int : length of IDs in packet.
1453 * int : length of clv we are decoding
1456 * void, but we will add to proto tree if !NULL.
1459 dissect_lsp_partition_dis_clv(tvbuff_t *tvb,
1460 packet_info *pinfo, proto_tree *tree, int offset,
1461 int id_length, int length)
1463 if ( length < id_length ) {
1464 isis_dissect_unknown(tvb, pinfo, tree, offset,
1465 "short lsp parition DIS(%d vs %d)", length,
1470 * Gotta build a sub-tree for all our pieces
1473 proto_tree_add_text ( tree, tvb, offset, id_length,
1474 "Partition designated L2 IS: %s",
1475 print_system_id( tvb_get_ptr(tvb, offset, id_length), id_length ) );
1477 length -= id_length;
1478 offset += id_length;
1480 isis_dissect_unknown(tvb, pinfo, tree, offset,
1481 "Long lsp parition DIS, %d left over", length );
1487 * Name: dissect_lsp_prefix_neighbors_clv()
1490 * The prefix CLV describes what other (OSI) networks we can reach
1491 * and what their cost is. It is built from a metric block
1492 * (see dissect_metric) followed by n addresses.
1495 * tvbuff_t * : tvbuffer for packet data
1496 * packet_info * : info for current packet
1497 * proto_tree * : protocol display tree to fill out. May be NULL
1498 * int : offset into packet data where we are.
1499 * int : length of IDs in packet.
1500 * int : length of clv we are decoding
1503 * void, but we will add to proto tree if !NULL.
1506 dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb,
1507 packet_info *pinfo, proto_tree *tree, int offset,
1508 int id_length, int length)
1514 isis_dissect_unknown(tvb, pinfo, tree, offset,
1515 "Short lsp prefix neighbors (%d vs 4)", length );
1519 dissect_metric (tvb, pinfo, tree, offset,
1520 tvb_get_guint8(tvb, offset), "Default", TRUE );
1521 dissect_metric (tvb, pinfo, tree, offset+1,
1522 tvb_get_guint8(tvb, offset+1), "Delay", FALSE );
1523 dissect_metric (tvb, pinfo, tree, offset+2,
1524 tvb_get_guint8(tvb, offset+2), "Expense", FALSE );
1525 dissect_metric (tvb, pinfo, tree, offset+3,
1526 tvb_get_guint8(tvb, offset+3), "Error", FALSE );
1530 while ( length > 0 ) {
1531 mylen = tvb_get_guint8(tvb, offset);
1534 isis_dissect_unknown(tvb, pinfo, tree, offset,
1535 "Zero payload space after length in prefix neighbor" );
1538 if ( mylen > length) {
1539 isis_dissect_unknown(tvb, pinfo, tree, offset,
1540 "Interal length of prefix neighbor too long (%d vs %d)",
1546 * Lets turn the area address into "standard" 0000.0000.etc
1549 sbuf = print_area( tvb_get_ptr(tvb, offset+1, mylen), mylen );
1550 /* and spit it out */
1552 proto_tree_add_text ( tree, tvb, offset, mylen + 1,
1553 "Area address (%d): %s", mylen, sbuf );
1555 offset += mylen + 1;
1556 length -= mylen; /* length already adjusted for len fld*/
1561 * Name: isis_lsp_decode_lsp_id()
1564 * Display a LSP id into the display tree.
1567 * tvbuff_t * : tvbuffer for packet data
1568 * packet_info * : info for current packet
1569 * proto_tree * : tree to display into. REQUIRED
1570 * int : offset into packet data where we are.
1571 * char * : title string
1572 * int : length of IDs in packet.
1575 * void, but we will add to proto tree
1578 isis_lsp_decode_lsp_id(tvbuff_t *tvb, packet_info *pinfo,
1579 proto_tree *tree, int offset, char *tstr, int id_length)
1581 proto_tree_add_text(tree, tvb, offset, id_length + 2,
1582 "%s: %s.%02x-%02x", tstr,
1583 print_system_id( tvb_get_ptr(tvb, offset, id_length), id_length ),
1584 tvb_get_guint8(tvb, offset+id_length),
1585 tvb_get_guint8(tvb, offset+id_length+1) );
1589 * Name: isis_dissect_isis_lsp()
1592 * Print out the LSP part of the main header and then call the CLV
1593 * de-mangler with the right list of valid CLVs.
1596 * tvbuff_t * : tvbuffer for packet data
1597 * packet_info * : info for current packet
1598 * proto_tree * : protocol display tree to add to. May be NULL.
1599 * int offset : our offset into packet data.
1600 * int : LSP type, a la packet-isis.h ISIS_TYPE_* values
1601 * int : header length of packet.
1602 * int : length of IDs in packet.
1605 * void, but we will add to proto tree if !NULL.
1608 isis_dissect_isis_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1609 int offset, int lsp_type, int header_length, int id_length)
1612 proto_tree *lsp_tree = NULL;
1615 int inx, q, some, value, len;
1617 if (!proto_is_protocol_enabled(proto_isis_lsp)) {
1618 call_dissector(data_handle,tvb_new_subset(tvb, offset, -1, tvb_reported_length_remaining(tvb,offset)),pinfo, tree);
1623 ti = proto_tree_add_item(tree, proto_isis_lsp, tvb,
1624 offset, tvb_length_remaining(tvb, offset), FALSE);
1625 lsp_tree = proto_item_add_subtree(ti, ett_isis_lsp);
1628 pdu_length = tvb_get_ntohs(tvb, offset);
1630 proto_tree_add_uint(lsp_tree, hf_isis_lsp_pdu_length, tvb,
1631 offset, 2, pdu_length);
1636 proto_tree_add_uint(lsp_tree, hf_isis_lsp_remaining_life, tvb,
1637 offset, 2, tvb_get_ntohs(tvb, offset));
1642 isis_lsp_decode_lsp_id(tvb, pinfo, lsp_tree, offset,
1643 "LSP ID", id_length);
1645 offset += id_length + 2;
1648 proto_tree_add_uint(lsp_tree, hf_isis_lsp_sequence_number, tvb,
1650 tvb_get_ntohl(tvb, offset));
1655 /* XXX -> we could validate the cksum here! */
1656 proto_tree_add_uint(lsp_tree, hf_isis_lsp_checksum, tvb,
1657 offset, 2, tvb_get_ntohs(tvb, offset));
1663 * We need to build our type block values.
1667 value = ISIS_LSP_ATT(tvb_get_guint8(tvb, offset));
1669 for ( q = (1<<ISIS_LSP_ATT_SHIFT); q > 0; q = q >> 1 ){
1674 strcat ( sbuf, isis_lsp_attached_bits[inx] );
1679 strcat ( sbuf, "default-only" );
1681 proto_tree_add_text(lsp_tree, tvb, offset + 18, 1,
1682 "Type block(0x%02x): P:%d, Supported metric(s): %s, OL:%d, istype:%s",
1683 tvb_get_guint8(tvb, offset),
1684 ISIS_LSP_PARTITION(tvb_get_guint8(tvb, offset)) ? 1 : 0,
1686 ISIS_LSP_HIPPITY(tvb_get_guint8(tvb, offset)) ? 1 : 0,
1687 val_to_str(ISIS_LSP_IS_TYPE(tvb_get_guint8(tvb, offset)),
1688 isis_lsp_istype_vals, "Unknown (0x%x)")
1693 len = pdu_length - header_length;
1695 isis_dissect_unknown(tvb, pinfo, tree, offset,
1696 "packet header length %d went beyond packet",
1701 * Now, we need to decode our CLVs. We need to pass in
1702 * our list of valid ones!
1704 if (lsp_type == ISIS_TYPE_L1_LSP){
1705 isis_dissect_clvs(tvb, pinfo, lsp_tree, offset,
1706 clv_l1_lsp_opts, len, id_length,
1707 ett_isis_lsp_clv_unknown );
1709 isis_dissect_clvs(tvb, pinfo, lsp_tree, offset,
1710 clv_l2_lsp_opts, len, id_length,
1711 ett_isis_lsp_clv_unknown );
1715 * Name: proto_register_isis_lsp()
1718 * Register our protocol sub-sets with protocol manager.
1719 * NOTE: this procedure is autolinked by the makefile process that
1723 proto_register_isis_lsp(void) {
1724 static hf_register_info hf[] = {
1725 { &hf_isis_lsp_pdu_length,
1726 { "PDU length", "isis_lsp.pdu_length", FT_UINT16,
1727 BASE_DEC, NULL, 0x0, "", HFILL }},
1729 { &hf_isis_lsp_remaining_life,
1730 { "Remaining lifetime", "isis_lsp.remaining_life", FT_UINT16,
1731 BASE_DEC, NULL, 0x0, "", HFILL }},
1733 { &hf_isis_lsp_sequence_number,
1734 { "Sequence number", "isis_lsp.sequence_number",
1735 FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1737 { &hf_isis_lsp_checksum,
1738 { "Checksum", "isis_lsp.checksum",FT_UINT16,
1739 BASE_HEX, NULL, 0x0, "", HFILL }},
1741 { &hf_isis_lsp_clv_ipv4_int_addr,
1742 { "IPv4 interface address", "isis_lsp.clv_ipv4_int_addr", FT_IPv4,
1743 BASE_NONE, NULL, 0x0, "", HFILL }},
1745 { &hf_isis_lsp_clv_ipv6_int_addr,
1746 { "IPv6 interface address", "isis_lsp.clv_ipv6_int_addr", FT_IPv6,
1747 BASE_NONE, NULL, 0x0, "", HFILL }},
1749 { &hf_isis_lsp_clv_te_router_id,
1750 { "Traffic Engineering Router ID", "isis_lsp.clv_te_router_id", FT_IPv4,
1751 BASE_NONE, NULL, 0x0, "", HFILL }},
1753 static gint *ett[] = {
1755 &ett_isis_lsp_clv_area_addr,
1756 &ett_isis_lsp_clv_is_neighbors,
1757 &ett_isis_lsp_clv_ext_is_reachability, /* CLV 22 */
1758 &ett_isis_lsp_part_of_clv_ext_is_reachability,
1759 &ett_isis_lsp_subclv_admin_group,
1760 &ett_isis_lsp_subclv_unrsv_bw,
1761 &ett_isis_lsp_clv_unknown,
1762 &ett_isis_lsp_clv_partition_dis,
1763 &ett_isis_lsp_clv_prefix_neighbors,
1764 &ett_isis_lsp_clv_auth,
1765 &ett_isis_lsp_clv_nlpid,
1766 &ett_isis_lsp_clv_hostname,
1767 &ett_isis_lsp_clv_ipv4_int_addr,
1768 &ett_isis_lsp_clv_ipv6_int_addr, /* CLV 232 */
1769 &ett_isis_lsp_clv_te_router_id,
1770 &ett_isis_lsp_clv_ip_reachability,
1771 &ett_isis_lsp_clv_ext_ip_reachability, /* CLV 135 */
1772 &ett_isis_lsp_part_of_clv_ext_ip_reachability,
1773 &ett_isis_lsp_clv_ipv6_reachability, /* CLV 236 */
1774 &ett_isis_lsp_part_of_clv_ipv6_reachability,
1775 &ett_isis_lsp_clv_mt,
1776 &ett_isis_lsp_clv_mt_is,
1777 &ett_isis_lsp_part_of_clv_mt_is,
1780 proto_isis_lsp = proto_register_protocol(PROTO_STRING_LSP,
1781 "ISIS LSP", "isis_lsp");
1782 proto_register_field_array(proto_isis_lsp, hf, array_length(hf));
1783 proto_register_subtree_array(ett, array_length(ett));
1787 proto_reg_handoff_isis_lsp(void){
1788 data_handle = find_dissector("data");