2 * Routines for decoding isis lsp packets and their CLVs
4 * $Id: packet-isis-lsp.c,v 1.20 2001/07/02 00:19:34 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.
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 const char *isis_lsp_attached_bits[] = {
90 "error", "expense", "delay", "default" };
92 static const value_string isis_lsp_istype_vals[] = {
93 { ISIS_LSP_TYPE_UNUSED0, "Unused 0x0 (invalid)"},
94 { ISIS_LSP_TYPE_LEVEL_1, "Level 1 IS"},
95 { ISIS_LSP_TYPE_UNUSED2, "Unused 0x2 (invalid)"},
96 { ISIS_LSP_TYPE_LEVEL_2, "Level 2 IS"},
100 * Predclare dissectors for use in clv dissection.
102 static void dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb,
103 packet_info *pinfo, proto_tree *tree, int offset,
104 int id_length, int length);
105 static void dissect_lsp_partition_dis_clv(tvbuff_t *tvb,
106 packet_info *pinfo, proto_tree *tree, int offset,
107 int id_length, int length);
108 static void dissect_lsp_mt_is_reachability_clv(tvbuff_t *tvb,
109 packet_info *pinfo, proto_tree *tree, int offset,
110 int id_length, int length);
111 static void dissect_lsp_ext_is_reachability_clv(tvbuff_t *tvb,
112 packet_info *pinfo, proto_tree *tree, int offset,
113 int id_length, int length);
114 static void dissect_lsp_l2_is_neighbors_clv(tvbuff_t *tvb,
115 packet_info *pinfo, proto_tree *tree, int offset,
116 int id_length, int length);
117 static void dissect_lsp_l1_es_neighbors_clv(tvbuff_t *tvb,
118 packet_info *pinfo, proto_tree *tree, int offset,
119 int id_length, int length);
120 static void dissect_lsp_l1_is_neighbors_clv(tvbuff_t *tvb,
121 packet_info *pinfo, proto_tree *tree, int offset,
122 int id_length, int length);
123 static void dissect_lsp_area_address_clv(tvbuff_t *tvb,
124 packet_info *pinfo, proto_tree *tree, int offset,
125 int id_length, int length);
126 static void dissect_lsp_l2_auth_clv(tvbuff_t *tvb,
127 packet_info *pinfo, proto_tree *tree, int offset,
128 int id_length, int length);
129 static void dissect_lsp_l1_auth_clv(tvbuff_t *tvb,
130 packet_info *pinfo, proto_tree *tree, int offset,
131 int id_length, int length);
132 static void dissect_lsp_ipv6_int_addr_clv(tvbuff_t *tvb,
133 packet_info *pinfo, proto_tree *tree, int offset,
134 int id_length, int length);
135 static void dissect_lsp_ip_int_addr_clv(tvbuff_t *tvb,
136 packet_info *pinfo, proto_tree *tree, int offset,
137 int id_length, int length);
138 static void dissect_lsp_te_router_id_clv(tvbuff_t *tvb,
139 packet_info *pinfo, proto_tree *tree, int offset,
140 int id_length, int length);
141 static void dissect_lsp_hostname_clv(tvbuff_t *tvb,
142 packet_info *pinfo, proto_tree *tree, int offset,
143 int id_length, int length);
144 static void dissect_lsp_mt_clv(tvbuff_t *tvb,
145 packet_info *pinfo, proto_tree *tree, int offset,
146 int id_length, int length);
147 static void dissect_lsp_nlpid_clv(tvbuff_t *tvb,
148 packet_info *pinfo, proto_tree *tree, int offset,
149 int id_length, int length);
150 static void dissect_lsp_ipv6_reachability_clv(tvbuff_t *tvb,
151 packet_info *pinfo, proto_tree *tree, int offset,
152 int id_length, int length);
153 static void dissect_lsp_ext_ip_reachability_clv(tvbuff_t *tvb,
154 packet_info *pinfo, proto_tree *tree, int offset,
155 int id_length, int length);
156 static void dissect_lsp_ip_reachability_clv(tvbuff_t *tvb,
157 packet_info *pinfo, proto_tree *tree, int offset,
158 int id_length, int length);
162 static const isis_clv_handle_t clv_l1_lsp_opts[] = {
164 ISIS_CLV_L1_LSP_AREA_ADDRESS,
166 &ett_isis_lsp_clv_area_addr,
167 dissect_lsp_area_address_clv
170 ISIS_CLV_L1_LSP_IS_NEIGHBORS,
172 &ett_isis_lsp_clv_is_neighbors,
173 dissect_lsp_l1_is_neighbors_clv
176 ISIS_CLV_L1_LSP_ES_NEIGHBORS,
178 &ett_isis_lsp_clv_is_neighbors,
179 dissect_lsp_l1_es_neighbors_clv
182 ISIS_CLV_L1_LSP_EXT_IS_REACHABLE,
183 "Extended IS reachability",
184 &ett_isis_lsp_clv_ext_is_reachability,
185 dissect_lsp_ext_is_reachability_clv
188 ISIS_CLV_L1_LSP_IP_INT_REACHABLE,
189 "IP Internal reachability",
190 &ett_isis_lsp_clv_ip_reachability,
191 dissect_lsp_ip_reachability_clv
194 ISIS_CLV_L1_LSP_IP_EXT_REACHABLE,
195 "IP External reachability",
196 &ett_isis_lsp_clv_ip_reachability,
197 dissect_lsp_ip_reachability_clv
200 ISIS_CLV_L1_LSP_EXT_IP_REACHABLE,
201 "Extended IP Reachability",
202 &ett_isis_lsp_clv_ext_ip_reachability,
203 dissect_lsp_ext_ip_reachability_clv
206 ISIS_CLV_L1_LSP_IPv6_REACHABLE,
208 &ett_isis_lsp_clv_ipv6_reachability,
209 dissect_lsp_ipv6_reachability_clv
212 ISIS_CLV_L1_LSP_NLPID,
213 "Protocols supported",
214 &ett_isis_lsp_clv_nlpid,
215 dissect_lsp_nlpid_clv
218 ISIS_CLV_L1_LSP_HOSTNAME,
220 &ett_isis_lsp_clv_hostname,
221 dissect_lsp_hostname_clv
224 ISIS_CLV_L1_LSP_TE_ROUTER_ID,
225 "Traffic Engineering Router ID",
226 &ett_isis_lsp_clv_te_router_id,
227 dissect_lsp_te_router_id_clv
230 ISIS_CLV_L1_LSP_IP_INTERFACE_ADDR,
231 "IP Interface address(es)",
232 &ett_isis_lsp_clv_ipv4_int_addr,
233 dissect_lsp_ip_int_addr_clv
236 ISIS_CLV_L1_LSP_IPv6_INTERFACE_ADDR,
237 "IPv6 Interface address(es)",
238 &ett_isis_lsp_clv_ipv6_int_addr,
239 dissect_lsp_ipv6_int_addr_clv
242 ISIS_CLV_L1_LSP_AUTHENTICATION_NS,
243 "Authentication(non-spec)",
244 &ett_isis_lsp_clv_auth,
245 dissect_lsp_l1_auth_clv
248 ISIS_CLV_L1_LSP_AUTHENTICATION,
250 &ett_isis_lsp_clv_auth,
251 dissect_lsp_l1_auth_clv
256 &ett_isis_lsp_clv_mt,
260 ISIS_CLV_L1_LSP_MT_IS_REACHABLE,
261 "Multi Topology IS Reachability",
262 &ett_isis_lsp_clv_mt_is,
263 dissect_lsp_mt_is_reachability_clv
274 static const isis_clv_handle_t clv_l2_lsp_opts[] = {
276 ISIS_CLV_L1_LSP_AREA_ADDRESS,
278 &ett_isis_lsp_clv_area_addr,
279 dissect_lsp_area_address_clv
282 ISIS_CLV_L2_LSP_IS_NEIGHBORS,
284 &ett_isis_lsp_clv_is_neighbors,
285 dissect_lsp_l2_is_neighbors_clv
288 ISIS_CLV_L2_LSP_EXT_IS_REACHABLE,
289 "Extended IS reachability",
290 &ett_isis_lsp_clv_ext_is_reachability,
291 dissect_lsp_ext_is_reachability_clv
294 ISIS_CLV_L2_LSP_PARTITION_DIS,
295 "Parition Designated Level 2 IS",
296 &ett_isis_lsp_clv_partition_dis,
297 dissect_lsp_partition_dis_clv
300 ISIS_CLV_L2_LSP_PREFIX_NEIGHBORS,
302 &ett_isis_lsp_clv_prefix_neighbors,
303 dissect_lsp_prefix_neighbors_clv
306 ISIS_CLV_L2_LSP_IP_INT_REACHABLE,
307 "IP Internal reachability",
308 &ett_isis_lsp_clv_ip_reachability,
309 dissect_lsp_ip_reachability_clv
312 ISIS_CLV_L2_LSP_IP_EXT_REACHABLE,
313 "IP External reachability",
314 &ett_isis_lsp_clv_ip_reachability,
315 dissect_lsp_ip_reachability_clv
318 ISIS_CLV_L2_LSP_NLPID,
319 "Protocols supported",
320 &ett_isis_lsp_clv_nlpid,
321 dissect_lsp_nlpid_clv
324 ISIS_CLV_L2_LSP_HOSTNAME,
326 &ett_isis_lsp_clv_hostname,
327 dissect_lsp_hostname_clv
330 ISIS_CLV_L2_LSP_TE_ROUTER_ID,
331 "Traffic Engineering Router ID",
332 &ett_isis_lsp_clv_te_router_id,
333 dissect_lsp_te_router_id_clv
336 ISIS_CLV_L2_LSP_EXT_IP_REACHABLE,
337 "Extended IP Reachability",
338 &ett_isis_lsp_clv_ext_ip_reachability,
339 dissect_lsp_ext_ip_reachability_clv
342 ISIS_CLV_L2_LSP_IPv6_REACHABLE,
344 &ett_isis_lsp_clv_ipv6_reachability,
345 dissect_lsp_ipv6_reachability_clv
348 ISIS_CLV_L2_LSP_IP_INTERFACE_ADDR,
349 "IP Interface address(es)",
350 &ett_isis_lsp_clv_ipv4_int_addr,
351 dissect_lsp_ip_int_addr_clv
354 ISIS_CLV_L2_LSP_IPv6_INTERFACE_ADDR,
355 "IPv6 Interface address(es)",
356 &ett_isis_lsp_clv_ipv6_int_addr,
357 dissect_lsp_ipv6_int_addr_clv
360 ISIS_CLV_L2_LSP_AUTHENTICATION_NS,
361 "Authentication(non spec)",
362 &ett_isis_lsp_clv_auth,
363 dissect_lsp_l2_auth_clv
366 ISIS_CLV_L2_LSP_AUTHENTICATION,
368 &ett_isis_lsp_clv_auth,
369 dissect_lsp_l2_auth_clv
374 &ett_isis_lsp_clv_mt,
378 ISIS_CLV_L2_LSP_MT_IS_REACHABLE,
379 "Multi Topology IS Reachability",
380 &ett_isis_lsp_clv_mt_is,
381 dissect_lsp_mt_is_reachability_clv
393 * Name: dissect_metric()
396 * Display a metric prefix portion. ISIS has the concept of multple
397 * metric per prefix (default, delay, expense, and error). This
398 * routine assists other dissectors by adding a single one of
399 * these to the display tree..
401 * The 8th(msbit) bit in the metric octet is the "supported" bit. The
402 * "default" support is required, so we support a "force_supported"
403 * flag that tells us that it MUST be zero (zero==supported,
404 * so it really should be a "not supported" in the boolean sense)
405 * and to display a protocol failure accordingly. Notably,
406 * Cisco IOS 12(6) blows this!
407 * The 7th bit must be zero (reserved).
410 * tvbuff_t * : tvbuffer for packet data
411 * packet_info * : info for current packet
412 * proto_tree * : protocol display tree to fill out. May be NULL
413 * int : offset into packet data where we are.
414 * guint8 : value of the metric.
415 * char * : string giving type of the metric.
416 * int : force supported. True is the supported bit MUST be zero.
419 * void, but we will add to proto tree if !NULL.
422 dissect_metric(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
423 int offset, guint8 value, char *pstr, int force_supported )
429 s = ISIS_LSP_CLV_METRIC_SUPPORTED(value);
430 proto_tree_add_text(tree, tvb, offset, 1,
431 "%s Metric: %s%s %s%d:%d", pstr,
432 s ? "Not supported" : "Supported",
433 (s && force_supported) ? "(but is required to be)":"",
434 ISIS_LSP_CLV_METRIC_RESERVED(value) ? "(reserved bit != 0)":"",
435 ISIS_LSP_CLV_METRIC_VALUE(value), value );
439 * Name: dissect_lsp_ip_reachability_clv()
442 * Decode an IP reachability CLV. This can be either internal or
443 * external (the clv format does not change and which type we are
444 * displaying is put there by the dispatcher). All of these
445 * are a metric block followed by an IP addr and mask.
448 * tvbuff_t * : tvbuffer for packet data
449 * packet_info * : info for current packet
450 * proto_tree * : proto tree to build on (may be null)
451 * int : current offset into packet data
452 * int : length of IDs in packet.
453 * int : length of this clv
456 * void, will modify proto_tree if not null.
459 dissect_lsp_ip_reachability_clv(tvbuff_t *tvb,
460 packet_info *pinfo, proto_tree *tree, int offset,
461 int id_length, int length)
464 proto_tree *ntree = NULL;
465 guint32 src, mask, prefix_len;
467 guint32 bitmasks[33] = {
469 0x00000008, 0x0000000c, 0x0000000e, 0x0000000f,
470 0x000000f8, 0x000000fc, 0x000000fe, 0x000000ff,
471 0x000008ff, 0x00000cff, 0x00000eff, 0x00000fff,
472 0x0000f8ff, 0x0000fcff, 0x0000feff, 0x0000ffff,
473 0x0008ffff, 0x000cffff, 0x000effff, 0x000fffff,
474 0x00f8ffff, 0x00fcffff, 0x00feffff, 0x00ffffff,
475 0x08ffffff, 0x0cffffff, 0x0effffff, 0x0fffffff,
476 0xf8ffffff, 0xfcffffff, 0xfeffffff, 0xffffffff
480 while ( length > 0 ) {
482 isis_dissect_unknown(tvb, pinfo, tree, offset,
483 "short IP reachability (%d vs 12)", length );
487 * Gotta build a sub-tree for all our pieces
490 tvb_memcpy(tvb, (guint8 *)&src, offset+4, 4);
491 tvb_memcpy(tvb, (guint8 *)&mask, offset+8, 4);
493 /* find out if the mask matches one of 33 possible prefix lengths */
497 while(prefix_len<=33) {
498 if (bitmasks[prefix_len++]==mask) {
504 /* 34 indicates no match -> must be a discontiguous netmask
505 lets dump the mask, otherwise print the prefix_len */
508 ti = proto_tree_add_text ( tree, tvb, offset, 12,
509 "IPv4 prefix: %s mask %s",
510 ip_to_str((guint8*)&src),
511 ip_to_str((guint8*)&mask));
513 ti = proto_tree_add_text ( tree, tvb, offset, 12,
514 "IPv4 prefix: %s/%d",
515 ip_to_str((guint8*)&src),
519 ntree = proto_item_add_subtree(ti,
520 ett_isis_lsp_clv_ip_reachability);
522 proto_tree_add_text (ntree, tvb, offset, 1,
523 "Default Metric: %d, %s, Distribution: %s",
524 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset)),
525 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset)) ? "External" : "Internal",
526 ISIS_LSP_CLV_METRIC_UPDOWN(tvb_get_guint8(tvb, offset)) ? "down" : "up");
529 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+1))) {
530 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: Not supported");
532 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: %d, %s",
533 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+1)),
534 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+1)) ? "External" : "Internal");
537 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+2))) {
538 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: Not supported");
540 proto_tree_add_text (ntree, tvb, offset+2, 1, "Exense Metric: %d, %s",
541 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+2)),
542 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+2)) ? "External" : "Internal");
545 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+3))) {
546 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: Not supported");
548 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: %d, %s",
549 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+3)),
550 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+3)) ? "External" : "Internal");
559 * Name: dissect_lsp_ext_ip_reachability_clv()
561 * Description: Decode an Extended IP Reachability CLV - code 135.
563 * The extended IP reachability TLV is an extended version
564 * of the IP reachability TLVs (codes 128 and 130). It encodes
565 * the metric as a 32-bit unsigned interger and allows to add
569 * tvbuff_t * : tvbuffer for packet data
570 * packet_info * : info for current packet
571 * proto_tree * : proto tree to build on (may be null)
572 * int : current offset into packet data
573 * int : length of IDs in packet.
574 * int : length of this clv
577 * void, will modify proto_tree if not null.
580 dissect_lsp_ext_ip_reachability_clv(tvbuff_t *tvb,
581 packet_info *pinfo, proto_tree *tree, int offset,
582 int id_length, int length)
584 proto_item *pi = NULL;
585 proto_tree *subtree = NULL;
587 guint8 bit_length, byte_length;
594 memset (prefix, 0, 4);
595 ctrl_info = tvb_get_guint8(tvb, offset+4);
596 bit_length = ctrl_info & 0x3f;
597 byte_length = (bit_length + 7) / 8;
598 tvb_memcpy (tvb, prefix, offset+5, byte_length);
599 pi = proto_tree_add_text (tree, tvb, offset, 0,
600 "IPv4 prefix: %s/%d",
603 subtree = proto_item_add_subtree (pi,
604 ett_isis_lsp_part_of_clv_ext_ip_reachability);
606 proto_tree_add_text (subtree, tvb, offset, 4,
607 "Metric: %d, Distribution: %s", tvb_get_ntohl(tvb, offset), ((ctrl_info & 0x80) == 0) ? "up" : "down" );
609 proto_tree_add_text (subtree, tvb, offset+4, 1,
610 "%s sub-TLVs present",
611 ((ctrl_info & 0x40) == 0) ? "no" : "" );
613 len = 5 + byte_length;
614 if ((ctrl_info & 0x40) != 0)
615 len += 1 + tvb_get_guint8(tvb, offset+len) ;
616 proto_item_set_len (pi, len);
623 * Name: dissect_lsp_ipv6_reachability_clv()
625 * Description: Decode an IPv6 reachability CLV - code 236.
628 * tvbuff_t * : tvbuffer for packet data
629 * packet_info * : info for current packet
630 * proto_tree * : proto tree to build on (may be null)
631 * int : current offset into packet data
632 * int : length of IDs in packet.
633 * int : length of this clv
636 * void, will modify proto_tree if not null.
639 dissect_lsp_ipv6_reachability_clv(tvbuff_t *tvb,
640 packet_info *pinfo, proto_tree *tree, int offset,
641 int id_length, int length)
644 proto_tree *ntree = NULL;
645 guint8 bit_length, byte_length;
646 struct e_in6_addr prefix;
653 memset (prefix.s6_addr, 0, 16);
656 bit_length = tvb_get_guint8(tvb, offset+5);
657 byte_length = (bit_length + 7) / 8;
658 tvb_memcpy (tvb, prefix.s6_addr, offset+6, byte_length);
659 ti = proto_tree_add_text (tree, tvb, offset, 0,
661 ip6_to_str (&prefix),
663 ntree = proto_item_add_subtree (ti, ett_isis_lsp_part_of_clv_ipv6_reachability);
665 metric = tvb_get_ntohl(tvb, offset);
666 proto_tree_add_text (ntree, tvb, offset, 4,
667 "Metric: %d", metric);
669 ctrl_info = tvb_get_guint8(tvb, offset+4);
670 proto_tree_add_text (ntree, tvb, offset+4, 1,
671 "Distribution: %s, %s",
672 ((ctrl_info & 0x80) == 0) ? "up" : "down",
673 ((ctrl_info & 0x40) == 0) ? "internal" : "external" );
675 proto_tree_add_text (ntree, tvb, offset+4, 1,
676 "Reserved bits: 0x%x",
677 (ctrl_info & 0x1f) );
678 proto_tree_add_text (ntree, tvb, offset+4, 1,
680 ((ctrl_info & 0x20) == 0) ? "no" : "yes" );
682 len = 6 + byte_length;
683 if ((ctrl_info & 0x20) != 0)
684 len += 1 + tvb_get_guint8(tvb, offset+len);
685 proto_item_set_len (ti, len);
692 * Name: dissect_lsp_nlpid_clv()
695 * Decode for a lsp packets NLPID clv. Calls into the
699 * tvbuff_t * : tvbuffer for packet data
700 * packet_info * : info for current packet
701 * proto_tree * : proto tree to build on (may be null)
702 * int : current offset into packet data
703 * int : length of IDs in packet.
704 * int : length of this clv
707 * void, will modify proto_tree if not null.
710 dissect_lsp_nlpid_clv(tvbuff_t *tvb,
711 packet_info *pinfo, proto_tree *tree, int offset,
712 int id_length, int length)
714 isis_dissect_nlpid_clv(tvb, pinfo, tree, offset, length);
718 * Name: dissect_lsp_mt_clv()
721 * Decode for a lsp packets Multi Topology clv. Calls into the
725 * u_char * : packet data
726 * int : current offset into packet data
727 * guint : length of this clv
728 * int : length of IDs in packet.
729 * frame_data * : frame data
730 * proto_tree * : proto tree to build on (may be null)
733 * void, will modify proto_tree if not null.
736 dissect_lsp_mt_clv(tvbuff_t *tvb,
737 packet_info *pinfo, proto_tree *tree, int offset,
738 int id_length, int length)
740 isis_dissect_mt_clv(tvb, pinfo, tree, offset, length,
741 hf_isis_lsp_clv_mt );
745 * Name: dissect_lsp_hostname_clv()
748 * Decode for a lsp packets hostname clv. Calls into the
752 * tvbuff_t * : tvbuffer for packet data
753 * packet_info * : info for current packet
754 * proto_tree * : proto tree to build on (may be null)
755 * int : current offset into packet data
756 * int : length of IDs in packet.
757 * int : length of this clv
760 * void, will modify proto_tree if not null.
763 dissect_lsp_hostname_clv(tvbuff_t *tvb,
764 packet_info *pinfo, proto_tree *tree, int offset,
765 int id_length, int length)
767 isis_dissect_hostname_clv(tvb, pinfo, tree, offset, length);
772 * Name: dissect_lsp_te_router_id_clv()
775 * Decode for a lsp packets Traffic Engineering ID clv. Calls into the
779 * tvbuff_t * : tvbuffer for packet data
780 * packet_info * : info for current packet
781 * proto_tree * : proto tree to build on (may be null)
782 * int : current offset into packet data
783 * int : length of IDs in packet.
784 * int : length of this clv
787 * void, will modify proto_tree if not null.
790 dissect_lsp_te_router_id_clv(tvbuff_t *tvb,
791 packet_info *pinfo, proto_tree *tree, int offset,
792 int id_length, int length)
794 isis_dissect_te_router_id_clv(tvb, pinfo, tree, offset, length,
795 hf_isis_lsp_clv_te_router_id );
800 * Name: dissect_lsp_ip_int_addr_clv()
803 * Decode for a lsp packets ip interface addr clv. Calls into the
807 * tvbuff_t * : tvbuffer for packet data
808 * packet_info * : info for current packet
809 * proto_tree * : proto tree to build on (may be null)
810 * int : current offset into packet data
811 * int : length of IDs in packet.
812 * int : length of this clv
815 * void, will modify proto_tree if not null.
818 dissect_lsp_ip_int_addr_clv(tvbuff_t *tvb,
819 packet_info *pinfo, proto_tree *tree, int offset,
820 int id_length, int length)
822 isis_dissect_ip_int_clv(tvb, pinfo, tree, offset, length,
823 hf_isis_lsp_clv_ipv4_int_addr );
827 * Name: dissect_lsp_ipv6_int_addr_clv()
829 * Description: Decode an IPv6 interface addr CLV - code 232.
831 * Calls into the clv common one.
834 * tvbuff_t * : tvbuffer for packet data
835 * packet_info * : info for current packet
836 * proto_tree * : proto tree to build on (may be null)
837 * int : current offset into packet data
838 * int : length of IDs in packet.
839 * int : length of this clv
842 * void, will modify proto_tree if not null.
845 dissect_lsp_ipv6_int_addr_clv(tvbuff_t *tvb,
846 packet_info *pinfo, proto_tree *tree, int offset,
847 int id_length, int length)
849 isis_dissect_ipv6_int_clv(tvb, pinfo, tree, offset, length,
850 hf_isis_lsp_clv_ipv6_int_addr );
854 * Name: dissect_lsp_L1_auth_clv()
857 * Decode for a lsp packets authenticaion clv. Calls into the
858 * clv common one. An auth inside a L1 LSP is a per area password
861 * tvbuff_t * : tvbuffer for packet data
862 * packet_info * : info for current packet
863 * proto_tree * : proto tree to build on (may be null)
864 * int : current offset into packet data
865 * int : length of IDs in packet.
866 * int : length of this clv
869 * void, will modify proto_tree if not null.
872 dissect_lsp_l1_auth_clv(tvbuff_t *tvb,
873 packet_info *pinfo, proto_tree *tree, int offset,
874 int id_length, int length)
876 isis_dissect_authentication_clv(tvb, pinfo, tree, offset, length,
877 "Per area authentication" );
881 * Name: dissect_lsp_L2_auth_clv()
884 * Decode for a lsp packets authenticaion clv. Calls into the
885 * clv common one. An auth inside a L2 LSP is a per domain password
888 * tvbuff_t * : tvbuffer for packet data
889 * packet_info * : info for current packet
890 * proto_tree * : proto tree to build on (may be null)
891 * int : current offset into packet data
892 * int : length of IDs in packet.
893 * int : length of this clv
896 * void, will modify proto_tree if not null.
899 dissect_lsp_l2_auth_clv(tvbuff_t *tvb,
900 packet_info *pinfo, proto_tree *tree, int offset,
901 int id_length, int length)
903 isis_dissect_authentication_clv(tvb, pinfo, tree, offset, length,
904 "Per domain authentication" );
908 * Name: dissect_lsp_area_address_clv()
911 * Decode for a lsp packet's area address clv. Call into clv common
915 * tvbuff_t * : tvbuffer for packet data
916 * packet_info * : info for current packet
917 * proto_tree * : protocol display tree to fill out. May be NULL
918 * int : offset into packet data where we are.
919 * int : length of IDs in packet.
920 * int : length of clv we are decoding
923 * void, but we will add to proto tree if !NULL.
926 dissect_lsp_area_address_clv(tvbuff_t *tvb,
927 packet_info *pinfo, proto_tree *tree, int offset,
928 int id_length, int length)
930 isis_dissect_area_address_clv(tvb, pinfo, tree, offset, length);
934 * Name: dissect_lsp_eis_neighbors_clv_inner()
937 * Real work horse for showing neighbors. This means we decode the
938 * first octet as either virtual/!virtual (if show_virtual param is
939 * set), or as a must == 0 reserved value.
941 * Once past that, we decode n neighbor elements. Each neighbor
942 * is comprised of a metric block (is dissect_metric) and the
946 * tvbuff_t * : tvbuffer for packet data
947 * packet_info * : info for current packet
948 * proto_tree * : protocol display tree to fill out. May be NULL
949 * int : offset into packet data where we are.
950 * int : length of IDs in packet.
951 * int : length of clv we are decoding
952 * int : set to decode first octet as virtual vs reserved == 0
953 * int : set to indicate EIS instead of IS (6 octet per addr instead of 7)
956 * void, but we will add to proto tree if !NULL.
959 dissect_lsp_eis_neighbors_clv_inner(tvbuff_t *tvb, packet_info *pinfo,
960 proto_tree *tree, int offset,
961 int length, int id_length, int show_virtual, int is_eis)
964 proto_tree *ntree = NULL;
968 id_length++; /* IDs are one octet longer in IS neighbours */
970 if ( show_virtual ) {
971 /* virtual path flag */
972 proto_tree_add_text ( tree, tvb, offset, 1,
973 tvb_get_guint8(tvb, offset) ? "IsNotVirtual" : "IsVirtual" );
975 proto_tree_add_text ( tree, tvb, offset, 1,
976 "Reserved value 0x%02x, must == 0",
977 tvb_get_guint8(tvb, offset) );
983 tlen = 4 + id_length;
985 while ( length > 0 ) {
987 isis_dissect_unknown(tvb, pinfo, tree, offset,
988 "short E/IS reachability (%d vs %d)", length,
993 * Gotta build a sub-tree for all our pieces
997 ti = proto_tree_add_text(tree, tvb, offset, tlen,
999 print_system_id( tvb_get_ptr(tvb, offset+4, id_length), id_length ) );
1001 ti = proto_tree_add_text(tree, tvb, offset, tlen,
1003 print_system_id(tvb_get_ptr(tvb, offset+4, id_length), id_length ) );
1005 ntree = proto_item_add_subtree(ti,
1006 ett_isis_lsp_clv_is_neighbors);
1010 proto_tree_add_text (ntree, tvb, offset, 1,
1011 "Default Metric: %d, %s",
1012 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset)),
1013 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset)) ? "External" : "Internal");
1015 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+1))) {
1016 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: Not supported");
1018 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: %d, %s",
1019 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+1)),
1020 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+1)) ? "External" : "Internal");
1024 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+2))) {
1025 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: Not supported");
1027 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: %d, %s",
1028 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+2)),
1029 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+2)) ? "External" : "Internal");
1032 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+3))) {
1033 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: Not supported");
1035 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: %d, %s",
1036 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+3)),
1037 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+3)) ? "External" : "Internal");
1047 * Name: dissect_lsp_l1_is_neighbors_clv()
1050 * Dispatch a l1 intermediate system neighbor by calling
1051 * the inner function with show virtual set to TRUE and is es set to FALSE.
1054 * tvbuff_t * : tvbuffer for packet data
1055 * packet_info * : info for current packet
1056 * proto_tree * : protocol display tree to fill out. May be NULL
1057 * int : offset into packet data where we are.
1058 * int : length of IDs in packet.
1059 * int : length of clv we are decoding
1062 * void, but we will add to proto tree if !NULL.
1065 dissect_lsp_l1_is_neighbors_clv(tvbuff_t *tvb,
1066 packet_info *pinfo, proto_tree *tree, int offset,
1067 int id_length, int length)
1069 dissect_lsp_eis_neighbors_clv_inner(tvb, pinfo, tree, offset,
1070 length, id_length, TRUE, FALSE);
1074 * Name: dissect_lsp_l1_es_neighbors_clv()
1077 * Dispatch a l1 end or intermediate system neighbor by calling
1078 * the inner function with show virtual set to TRUE and es set to TRUE.
1081 * tvbuff_t * : tvbuffer for packet data
1082 * packet_info * : info for current packet
1083 * proto_tree * : protocol display tree to fill out. May be NULL
1084 * int : offset into packet data where we are.
1085 * int : length of IDs in packet.
1086 * int : length of clv we are decoding
1089 * void, but we will add to proto tree if !NULL.
1092 dissect_lsp_l1_es_neighbors_clv(tvbuff_t *tvb,
1093 packet_info *pinfo, proto_tree *tree, int offset,
1094 int id_length, int length)
1096 dissect_lsp_eis_neighbors_clv_inner(tvb, pinfo, tree, offset,
1097 length, id_length, TRUE, TRUE);
1101 * Name: dissect_lsp_l2_is_neighbors_clv()
1104 * Dispatch a l2 intermediate system neighbor by calling
1105 * the inner function with show virtual set to FALSE, and is es set
1109 * tvbuff_t * : tvbuffer for packet data
1110 * packet_info * : info for current packet
1111 * proto_tree * : protocol display tree to fill out. May be NULL
1112 * int : offset into packet data where we are.
1113 * int : length of IDs in packet.
1114 * int : length of clv we are decoding
1117 * void, but we will add to proto tree if !NULL.
1120 dissect_lsp_l2_is_neighbors_clv(tvbuff_t *tvb,
1121 packet_info *pinfo, proto_tree *tree, int offset,
1122 int id_length, int length)
1124 dissect_lsp_eis_neighbors_clv_inner(tvb, pinfo, tree, offset,
1125 length, id_length, FALSE, FALSE);
1130 * Name: dissect_subclv_admin_group ()
1132 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1134 * This function is called by dissect_lsp_ext_is_reachability_clv()
1135 * for dissect the administrive group sub-CLV (code 3).
1138 * tvbuff_t * : tvbuffer for packet data
1139 * packet_info * : info for current packet
1140 * proto_tree * : protocol display tree to fill out.
1141 * int : offset into packet data where we are (beginning of the sub_clv value).
1147 dissect_subclv_admin_group (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset) {
1154 ti = proto_tree_add_text(tree, tvb, offset-2, 6, "Administrative group(s):");
1155 ntree = proto_item_add_subtree (ti, ett_isis_lsp_subclv_admin_group);
1157 clv_value = tvb_get_ntohl(tvb, offset);
1159 for (i = 0 ; i < 32 ; i++) {
1160 if ( (clv_value & mask) != 0 ) {
1161 proto_tree_add_text (ntree, tvb, offset, 4, "group %d", i);
1168 * Name: dissect_subclv_max_bw ()
1170 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1172 * This function is called by dissect_lsp_ext_is_reachability_clv()
1173 * for dissect the maximum link bandwidth sub-CLV (code 9).
1176 * u_char * : packet data
1177 * int : offset into packet data where we are (beginning of the sub_clv value).
1178 * proto_tree * : protocol display tree to fill out.
1184 dissect_subclv_max_bw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1189 ui = tvb_get_ntohl(tvb, offset);
1190 memcpy (&bw, &ui, 4);
1191 proto_tree_add_text (tree, tvb, offset-2, 6,
1192 "Maximum link bandwidth : %.2f Mbps", bw*8/1000000 );
1196 * Name: dissect_subclv_rsv_bw ()
1198 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1200 * This function is called by dissect_lsp_ext_is_reachability_clv()
1201 * for dissect the reservable link bandwidth sub-CLV (code 10).
1204 * u_char * : packet data
1205 * int : offset into packet data where we are (beginning of the sub_clv value).
1206 * proto_tree * : protocol display tree to fill out.
1212 dissect_subclv_rsv_bw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1217 ui = tvb_get_ntohl(tvb, offset);
1218 memcpy (&bw, &ui, 4);
1219 proto_tree_add_text (tree, tvb, offset-2, 6,
1220 "Reservable link bandwidth: %.2f Mbps", bw*8/1000000 );
1224 * Name: dissect_subclv_unrsv_bw ()
1226 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1228 * This function is called by dissect_lsp_ext_is_reachability_clv()
1229 * for dissect the unreserved bandwidth sub-CLV (code 11).
1232 * u_char * : packet data
1233 * int : offset into packet data where we are (beginning of the sub_clv value).
1234 * proto_tree * : protocol display tree to fill out.
1240 dissect_subclv_unrsv_bw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1248 ti = proto_tree_add_text (tree, tvb, offset-2, 34, "Unreserved bandwidth:");
1249 ntree = proto_item_add_subtree (ti, ett_isis_lsp_subclv_unrsv_bw);
1251 for (i = 0 ; i < 8 ; i++) {
1252 ui = tvb_get_ntohl(tvb, offset);;
1253 memcpy (&bw, &ui, 4);
1254 proto_tree_add_text (ntree, tvb, offset+4*i, 4,
1255 "priority level %d: %.2f Mbps", i, bw*8/1000000 );
1260 * Name: dissect_lsp_ext_is_reachability_clv()
1262 * Description: Decode a Extended IS Reachability CLV - code 22
1264 * The extended IS reachability TLV is an extended version
1265 * of the IS reachability TLV (code 2). It encodes the metric
1266 * as a 24-bit unsigned interger and allows to add sub-CLV(s).
1269 * tvbuff_t * : tvbuffer for packet data
1270 * packet_info * : info for current packet
1271 * proto_tree * : protocol display tree to fill out. May be NULL
1272 * int : offset into packet data where we are.
1273 * int : length of IDs in packet.
1274 * int : length of clv we are decoding
1277 * void, but we will add to proto tree if !NULL.
1280 dissect_lsp_ext_is_reachability_clv(tvbuff_t *tvb,
1281 packet_info *pinfo, proto_tree *tree, int offset,
1282 int id_length, int length)
1285 proto_tree *ntree = NULL;
1288 guint8 clv_code, clv_len;
1292 while (length > 0) {
1293 ti = proto_tree_add_text (tree, tvb, offset, 0,
1295 print_system_id (tvb_get_ptr(tvb, offset, 7), 7) );
1296 ntree = proto_item_add_subtree (ti,
1297 ett_isis_lsp_part_of_clv_ext_is_reachability );
1299 proto_tree_add_text (ntree, tvb, offset+7, 3,
1300 "Metric: %d", tvb_get_ntoh24(tvb, offset+7) );
1302 subclvs_len = tvb_get_guint8(tvb, offset+10);
1303 if (subclvs_len == 0) {
1304 proto_tree_add_text (ntree, tvb, offset+10, 1, "no sub-TLVs present");
1308 while (i < subclvs_len) {
1309 clv_code = tvb_get_guint8(tvb, offset+11+i);
1310 clv_len = tvb_get_guint8(tvb, offset+12+i);
1313 dissect_subclv_admin_group(tvb, pinfo, ntree, offset+13+i);
1316 proto_tree_add_text (ntree, tvb, offset+11+i, 6,
1317 "IPv4 interface address: %s", ip_to_str (tvb_get_ptr(tvb, offset+13+i, 4)) );
1320 proto_tree_add_text (ntree, tvb, offset+11+i, 6,
1321 "IPv4 neighbor address: %s", ip_to_str (tvb_get_ptr(tvb, offset+13+i, 4)) );
1324 dissect_subclv_max_bw (tvb, pinfo, ntree, offset+13+i);
1327 dissect_subclv_rsv_bw (tvb, pinfo, ntree, offset+13+i);
1330 dissect_subclv_unrsv_bw (tvb, pinfo, ntree, offset+13+i);
1333 proto_tree_add_text (ntree, tvb, offset+11+i, 5,
1334 "Traffic engineering default metric: %d",
1335 tvb_get_ntoh24(tvb, offset+13+i) );
1342 proto_tree_add_text (ntree, tvb, offset+11+i, clv_len+2,
1343 "Unknown Cisco specific extensions: code %d, length %d",
1344 clv_code, clv_len );
1347 proto_tree_add_text (ntree, tvb, offset+11+i, clv_len+2,
1348 "Unknown sub-CLV: code %d, length %d", clv_code, clv_len );
1355 len = 11 + subclvs_len;
1356 proto_item_set_len (ti, len);
1367 static void dissect_lsp_mt_is_reachability_clv(tvbuff_t *tvb,
1368 packet_info *pinfo, proto_tree *tree, int offset,
1369 int id_length, int length)
1372 proto_tree *ntree = NULL;
1381 while (length > 0) {
1383 /* fetch two bytes */
1384 mt_block = tvb_get_ntohs(tvb, offset);
1386 /* mask out the lower 12 bits */
1387 switch(mt_block&0x0fff) {
1389 strcpy(mt_desc,"IPv4 unicast");
1392 strcpy(mt_desc,"In-Band Management");
1395 strcpy(mt_desc,"IPv6 unicast");
1398 strcpy(mt_desc,"Multicast");
1401 strcpy(mt_desc,"Development, Experimental or Proprietary");
1404 strcpy(mt_desc,"Reserved for IETF Consensus");
1407 proto_tree_add_text ( tree, tvb, offset, 2 ,
1408 "%s Topology (0x%x)",
1412 ti = proto_tree_add_text (tree, tvb, offset+2, 0,
1414 print_system_id(tvb_get_ptr(tvb, offset+2, 7), 7) );
1416 ntree = proto_item_add_subtree (ti,
1417 ett_isis_lsp_part_of_clv_mt_is );
1419 proto_tree_add_text (ntree, tvb, offset+9, 3,
1420 "Metric: %d", tvb_get_ntoh24(tvb, offset+9) );
1422 subclvs_len = tvb_get_guint8(tvb, offset+12);
1423 if (subclvs_len == 0) {
1424 proto_tree_add_text (ntree, tvb, offset+12, 1, "no sub-TLVs present");
1426 proto_tree_add_text (ntree, tvb, offset+12, 1, "sub-TLVs present");
1429 len = 13 + subclvs_len;
1430 proto_item_set_len (ti, len);
1438 * Name: dissect_lsp_partition_dis_clv()
1441 * This CLV is used to indicate which system is the designated
1442 * IS for partition repair. This means just putting out the
1443 * "id_length"-octet IS.
1446 * tvbuff_t * : tvbuffer for packet data
1447 * packet_info * : info for current packet
1448 * proto_tree * : protocol display tree to fill out. May be NULL
1449 * int : offset into packet data where we are.
1450 * int : length of IDs in packet.
1451 * int : length of clv we are decoding
1454 * void, but we will add to proto tree if !NULL.
1457 dissect_lsp_partition_dis_clv(tvbuff_t *tvb,
1458 packet_info *pinfo, proto_tree *tree, int offset,
1459 int id_length, int length)
1461 if ( length < id_length ) {
1462 isis_dissect_unknown(tvb, pinfo, tree, offset,
1463 "short lsp parition DIS(%d vs %d)", length,
1468 * Gotta build a sub-tree for all our pieces
1471 proto_tree_add_text ( tree, tvb, offset, id_length,
1472 "Partition designated L2 IS: %s",
1473 print_system_id( tvb_get_ptr(tvb, offset, id_length), id_length ) );
1475 length -= id_length;
1476 offset += id_length;
1478 isis_dissect_unknown(tvb, pinfo, tree, offset,
1479 "Long lsp parition DIS, %d left over", length );
1485 * Name: dissect_lsp_prefix_neighbors_clv()
1488 * The prefix CLV describes what other (OSI) networks we can reach
1489 * and what their cost is. It is built from a metric block
1490 * (see dissect_metric) followed by n addresses.
1493 * tvbuff_t * : tvbuffer for packet data
1494 * packet_info * : info for current packet
1495 * proto_tree * : protocol display tree to fill out. May be NULL
1496 * int : offset into packet data where we are.
1497 * int : length of IDs in packet.
1498 * int : length of clv we are decoding
1501 * void, but we will add to proto tree if !NULL.
1504 dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb,
1505 packet_info *pinfo, proto_tree *tree, int offset,
1506 int id_length, int length)
1512 isis_dissect_unknown(tvb, pinfo, tree, offset,
1513 "Short lsp prefix neighbors (%d vs 4)", length );
1517 dissect_metric (tvb, pinfo, tree, offset,
1518 tvb_get_guint8(tvb, offset), "Default", TRUE );
1519 dissect_metric (tvb, pinfo, tree, offset+1,
1520 tvb_get_guint8(tvb, offset+1), "Delay", FALSE );
1521 dissect_metric (tvb, pinfo, tree, offset+2,
1522 tvb_get_guint8(tvb, offset+2), "Expense", FALSE );
1523 dissect_metric (tvb, pinfo, tree, offset+3,
1524 tvb_get_guint8(tvb, offset+3), "Error", FALSE );
1528 while ( length > 0 ) {
1529 mylen = tvb_get_guint8(tvb, offset);
1532 isis_dissect_unknown(tvb, pinfo, tree, offset,
1533 "Zero payload space after length in prefix neighbor" );
1536 if ( mylen > length) {
1537 isis_dissect_unknown(tvb, pinfo, tree, offset,
1538 "Interal length of prefix neighbor too long (%d vs %d)",
1544 * Lets turn the area address into "standard" 0000.0000.etc
1547 sbuf = print_area( tvb_get_ptr(tvb, offset+1, mylen), mylen );
1548 /* and spit it out */
1550 proto_tree_add_text ( tree, tvb, offset, mylen + 1,
1551 "Area address (%d): %s", mylen, sbuf );
1553 offset += mylen + 1;
1554 length -= mylen; /* length already adjusted for len fld*/
1559 * Name: isis_lsp_decode_lsp_id()
1562 * Display a LSP id into the display tree.
1565 * tvbuff_t * : tvbuffer for packet data
1566 * packet_info * : info for current packet
1567 * proto_tree * : tree to display into. REQUIRED
1568 * int : offset into packet data where we are.
1569 * char * : title string
1570 * int : length of IDs in packet.
1573 * void, but we will add to proto tree
1576 isis_lsp_decode_lsp_id(tvbuff_t *tvb, packet_info *pinfo,
1577 proto_tree *tree, int offset, char *tstr, int id_length)
1579 proto_tree_add_text(tree, tvb, offset, id_length + 2,
1580 "%s: %s.%02x-%02x", tstr,
1581 print_system_id( tvb_get_ptr(tvb, offset, id_length), id_length ),
1582 tvb_get_guint8(tvb, offset+id_length),
1583 tvb_get_guint8(tvb, offset+id_length+1) );
1587 * Name: isis_dissect_isis_lsp()
1590 * Print out the LSP part of the main header and then call the CLV
1591 * de-mangler with the right list of valid CLVs.
1594 * tvbuff_t * : tvbuffer for packet data
1595 * packet_info * : info for current packet
1596 * proto_tree * : protocol display tree to add to. May be NULL.
1597 * int offset : our offset into packet data.
1598 * int : LSP type, a la packet-isis.h ISIS_TYPE_* values
1599 * int : header length of packet.
1600 * int : length of IDs in packet.
1603 * void, but we will add to proto tree if !NULL.
1606 isis_dissect_isis_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1607 int offset, int lsp_type, int header_length, int id_length)
1610 proto_tree *lsp_tree = NULL;
1613 int inx, q, some, value, len;
1615 if (!proto_is_protocol_enabled(proto_isis_lsp)) {
1616 dissect_data(tvb, offset, pinfo, tree);
1621 ti = proto_tree_add_item(tree, proto_isis_lsp, tvb,
1622 offset, tvb_length_remaining(tvb, offset), FALSE);
1623 lsp_tree = proto_item_add_subtree(ti, ett_isis_lsp);
1626 pdu_length = tvb_get_ntohs(tvb, offset);
1628 proto_tree_add_uint(lsp_tree, hf_isis_lsp_pdu_length, tvb,
1629 offset, 2, pdu_length);
1634 proto_tree_add_uint(lsp_tree, hf_isis_lsp_remaining_life, tvb,
1635 offset, 2, tvb_get_ntohs(tvb, offset));
1640 isis_lsp_decode_lsp_id(tvb, pinfo, lsp_tree, offset,
1641 "LSP ID", id_length);
1643 offset += id_length + 2;
1646 proto_tree_add_uint(lsp_tree, hf_isis_lsp_sequence_number, tvb,
1648 tvb_get_ntohl(tvb, offset));
1653 /* XXX -> we could validate the cksum here! */
1654 proto_tree_add_uint(lsp_tree, hf_isis_lsp_checksum, tvb,
1655 offset, 2, tvb_get_ntohs(tvb, offset));
1661 * We need to build our type block values.
1665 value = ISIS_LSP_ATT(tvb_get_guint8(tvb, offset));
1667 for ( q = (1<<ISIS_LSP_ATT_SHIFT); q > 0; q = q >> 1 ){
1672 strcat ( sbuf, isis_lsp_attached_bits[inx] );
1677 strcat ( sbuf, "default-only" );
1679 proto_tree_add_text(lsp_tree, tvb, offset + 18, 1,
1680 "Type block(0x%02x): P:%d, Supported metric(s): %s, OL:%d, istype:%s",
1681 tvb_get_guint8(tvb, offset),
1682 ISIS_LSP_PARTITION(tvb_get_guint8(tvb, offset)) ? 1 : 0,
1684 ISIS_LSP_HIPPITY(tvb_get_guint8(tvb, offset)) ? 1 : 0,
1685 val_to_str(ISIS_LSP_IS_TYPE(tvb_get_guint8(tvb, offset)),
1686 isis_lsp_istype_vals, "Unknown (0x%x)")
1691 len = pdu_length - header_length;
1693 isis_dissect_unknown(tvb, pinfo, tree, offset,
1694 "packet header length %d went beyond packet",
1699 * Now, we need to decode our CLVs. We need to pass in
1700 * our list of valid ones!
1702 if (lsp_type == ISIS_TYPE_L1_LSP){
1703 isis_dissect_clvs(tvb, pinfo, lsp_tree, offset,
1704 clv_l1_lsp_opts, len, id_length,
1705 ett_isis_lsp_clv_unknown );
1707 isis_dissect_clvs(tvb, pinfo, lsp_tree, offset,
1708 clv_l2_lsp_opts, len, id_length,
1709 ett_isis_lsp_clv_unknown );
1713 * Name: proto_register_isis_lsp()
1716 * Register our protocol sub-sets with protocol manager.
1717 * NOTE: this procedure is autolinked by the makefile process that
1721 proto_register_isis_lsp(void) {
1722 static hf_register_info hf[] = {
1723 { &hf_isis_lsp_pdu_length,
1724 { "PDU length", "isis_lsp.pdu_length", FT_UINT16,
1725 BASE_DEC, NULL, 0x0, "", HFILL }},
1727 { &hf_isis_lsp_remaining_life,
1728 { "Remaining lifetime", "isis_lsp.remaining_life", FT_UINT16,
1729 BASE_DEC, NULL, 0x0, "", HFILL }},
1731 { &hf_isis_lsp_sequence_number,
1732 { "Sequence number", "isis_lsp.sequence_number",
1733 FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1735 { &hf_isis_lsp_checksum,
1736 { "Checksum", "isis_lsp.checksum",FT_UINT16,
1737 BASE_HEX, NULL, 0x0, "", HFILL }},
1739 { &hf_isis_lsp_clv_ipv4_int_addr,
1740 { "IPv4 interface address", "isis_lsp.clv_ipv4_int_addr", FT_IPv4,
1741 BASE_NONE, NULL, 0x0, "", HFILL }},
1743 { &hf_isis_lsp_clv_ipv6_int_addr,
1744 { "IPv6 interface address", "isis_lsp.clv_ipv6_int_addr", FT_IPv6,
1745 BASE_NONE, NULL, 0x0, "", HFILL }},
1747 { &hf_isis_lsp_clv_te_router_id,
1748 { "Traffic Engineering Router ID", "isis_lsp.clv_te_router_id", FT_IPv4,
1749 BASE_NONE, NULL, 0x0, "", HFILL }},
1751 static gint *ett[] = {
1753 &ett_isis_lsp_clv_area_addr,
1754 &ett_isis_lsp_clv_is_neighbors,
1755 &ett_isis_lsp_clv_ext_is_reachability, /* CLV 22 */
1756 &ett_isis_lsp_part_of_clv_ext_is_reachability,
1757 &ett_isis_lsp_subclv_admin_group,
1758 &ett_isis_lsp_subclv_unrsv_bw,
1759 &ett_isis_lsp_clv_unknown,
1760 &ett_isis_lsp_clv_partition_dis,
1761 &ett_isis_lsp_clv_prefix_neighbors,
1762 &ett_isis_lsp_clv_auth,
1763 &ett_isis_lsp_clv_nlpid,
1764 &ett_isis_lsp_clv_hostname,
1765 &ett_isis_lsp_clv_ipv4_int_addr,
1766 &ett_isis_lsp_clv_ipv6_int_addr, /* CLV 232 */
1767 &ett_isis_lsp_clv_te_router_id,
1768 &ett_isis_lsp_clv_ip_reachability,
1769 &ett_isis_lsp_clv_ext_ip_reachability, /* CLV 135 */
1770 &ett_isis_lsp_part_of_clv_ext_ip_reachability,
1771 &ett_isis_lsp_clv_ipv6_reachability, /* CLV 236 */
1772 &ett_isis_lsp_part_of_clv_ipv6_reachability,
1773 &ett_isis_lsp_clv_mt,
1774 &ett_isis_lsp_clv_mt_is,
1775 &ett_isis_lsp_part_of_clv_mt_is,
1778 proto_isis_lsp = proto_register_protocol(PROTO_STRING_LSP,
1779 "ISIS LSP", "isis_lsp");
1780 proto_register_field_array(proto_isis_lsp, hf, array_length(hf));
1781 proto_register_subtree_array(ett, array_length(ett));