2 * Routines for decoding isis lsp packets and their CLVs
4 * $Id: packet-isis-lsp.c,v 1.25 2002/01/21 07:36:36 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.
30 #ifdef HAVE_SYS_TYPES_H
31 # include <sys/types.h>
38 #ifdef HAVE_NET_INET_H
42 #include "epan/ipv4.h"
43 #include <epan/packet.h>
44 #include "packet-osi.h"
45 #include "packet-ipv6.h"
46 #include "packet-isis.h"
47 #include "packet-isis-clv.h"
48 #include "packet-isis-lsp.h"
49 #include <epan/resolv.h>
52 static int hf_isis_lsp_pdu_length = -1;
53 static int hf_isis_lsp_remaining_life = -1;
54 static int hf_isis_lsp_sequence_number = -1;
55 static int hf_isis_lsp_checksum = -1;
56 static int hf_isis_lsp_clv_ipv4_int_addr = -1;
57 static int hf_isis_lsp_clv_ipv6_int_addr = -1;
58 static int hf_isis_lsp_clv_te_router_id = -1;
59 static int hf_isis_lsp_clv_mt = -1;
61 static gint ett_isis_lsp = -1;
62 static gint ett_isis_lsp_clv_area_addr = -1;
63 static gint ett_isis_lsp_clv_is_neighbors = -1;
64 static gint ett_isis_lsp_clv_ext_is_reachability = -1; /* CLV 22 */
65 static gint ett_isis_lsp_part_of_clv_ext_is_reachability = -1;
66 static gint ett_isis_lsp_subclv_admin_group = -1;
67 static gint ett_isis_lsp_subclv_unrsv_bw = -1;
68 static gint ett_isis_lsp_clv_unknown = -1;
69 static gint ett_isis_lsp_clv_partition_dis = -1;
70 static gint ett_isis_lsp_clv_prefix_neighbors = -1;
71 static gint ett_isis_lsp_clv_nlpid = -1;
72 static gint ett_isis_lsp_clv_hostname = -1;
73 static gint ett_isis_lsp_clv_te_router_id = -1;
74 static gint ett_isis_lsp_clv_auth = -1;
75 static gint ett_isis_lsp_clv_ipv4_int_addr = -1;
76 static gint ett_isis_lsp_clv_ipv6_int_addr = -1; /* CLV 232 */
77 static gint ett_isis_lsp_clv_ip_reachability = -1;
78 static gint ett_isis_lsp_clv_ext_ip_reachability = -1; /* CLV 135 */
79 static gint ett_isis_lsp_part_of_clv_ext_ip_reachability = -1;
80 static gint ett_isis_lsp_clv_ipv6_reachability = -1; /* CLV 236 */
81 static gint ett_isis_lsp_part_of_clv_ipv6_reachability = -1;
82 static gint ett_isis_lsp_clv_mt = -1;
83 static gint ett_isis_lsp_clv_mt_is = -1;
84 static gint ett_isis_lsp_part_of_clv_mt_is = -1;
86 static const char *isis_lsp_attached_bits[] = {
87 "error", "expense", "delay", "default" };
89 static const value_string isis_lsp_istype_vals[] = {
90 { ISIS_LSP_TYPE_UNUSED0, "Unused 0x0 (invalid)"},
91 { ISIS_LSP_TYPE_LEVEL_1, "Level 1 IS"},
92 { ISIS_LSP_TYPE_UNUSED2, "Unused 0x2 (invalid)"},
93 { ISIS_LSP_TYPE_LEVEL_2, "Level 1 and Level 2 IS"},
97 * Predclare dissectors for use in clv dissection.
99 static void dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb,
100 packet_info *pinfo, proto_tree *tree, int offset,
101 int id_length, int length);
102 static void dissect_lsp_partition_dis_clv(tvbuff_t *tvb,
103 packet_info *pinfo, proto_tree *tree, int offset,
104 int id_length, int length);
105 static void dissect_lsp_mt_is_reachability_clv(tvbuff_t *tvb,
106 packet_info *pinfo, proto_tree *tree, int offset,
107 int id_length, int length);
108 static void dissect_lsp_ext_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_l2_is_neighbors_clv(tvbuff_t *tvb,
112 packet_info *pinfo, proto_tree *tree, int offset,
113 int id_length, int length);
114 static void dissect_lsp_l1_es_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_is_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_area_address_clv(tvbuff_t *tvb,
121 packet_info *pinfo, proto_tree *tree, int offset,
122 int id_length, int length);
123 static void dissect_lsp_l2_auth_clv(tvbuff_t *tvb,
124 packet_info *pinfo, proto_tree *tree, int offset,
125 int id_length, int length);
126 static void dissect_lsp_l1_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_ipv6_int_addr_clv(tvbuff_t *tvb,
130 packet_info *pinfo, proto_tree *tree, int offset,
131 int id_length, int length);
132 static void dissect_lsp_ip_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_te_router_id_clv(tvbuff_t *tvb,
136 packet_info *pinfo, proto_tree *tree, int offset,
137 int id_length, int length);
138 static void dissect_lsp_hostname_clv(tvbuff_t *tvb,
139 packet_info *pinfo, proto_tree *tree, int offset,
140 int id_length, int length);
141 static void dissect_lsp_mt_clv(tvbuff_t *tvb,
142 packet_info *pinfo, proto_tree *tree, int offset,
143 int id_length, int length);
144 static void dissect_lsp_nlpid_clv(tvbuff_t *tvb,
145 packet_info *pinfo, proto_tree *tree, int offset,
146 int id_length, int length);
147 static void dissect_lsp_ipv6_reachability_clv(tvbuff_t *tvb,
148 packet_info *pinfo, proto_tree *tree, int offset,
149 int id_length, int length);
150 static void dissect_lsp_ext_ip_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_ip_reachability_clv(tvbuff_t *tvb,
154 packet_info *pinfo, proto_tree *tree, int offset,
155 int id_length, int length);
159 static const isis_clv_handle_t clv_l1_lsp_opts[] = {
161 ISIS_CLV_L1_LSP_AREA_ADDRESS,
163 &ett_isis_lsp_clv_area_addr,
164 dissect_lsp_area_address_clv
167 ISIS_CLV_L1_LSP_IS_NEIGHBORS,
169 &ett_isis_lsp_clv_is_neighbors,
170 dissect_lsp_l1_is_neighbors_clv
173 ISIS_CLV_L1_LSP_ES_NEIGHBORS,
175 &ett_isis_lsp_clv_is_neighbors,
176 dissect_lsp_l1_es_neighbors_clv
179 ISIS_CLV_L1_LSP_EXT_IS_REACHABLE,
180 "Extended IS reachability",
181 &ett_isis_lsp_clv_ext_is_reachability,
182 dissect_lsp_ext_is_reachability_clv
185 ISIS_CLV_L1_LSP_IP_INT_REACHABLE,
186 "IP Internal reachability",
187 &ett_isis_lsp_clv_ip_reachability,
188 dissect_lsp_ip_reachability_clv
191 ISIS_CLV_L1_LSP_IP_EXT_REACHABLE,
192 "IP External reachability",
193 &ett_isis_lsp_clv_ip_reachability,
194 dissect_lsp_ip_reachability_clv
197 ISIS_CLV_L1_LSP_EXT_IP_REACHABLE,
198 "Extended IP Reachability",
199 &ett_isis_lsp_clv_ext_ip_reachability,
200 dissect_lsp_ext_ip_reachability_clv
203 ISIS_CLV_L1_LSP_IPv6_REACHABLE,
205 &ett_isis_lsp_clv_ipv6_reachability,
206 dissect_lsp_ipv6_reachability_clv
209 ISIS_CLV_L1_LSP_NLPID,
210 "Protocols supported",
211 &ett_isis_lsp_clv_nlpid,
212 dissect_lsp_nlpid_clv
215 ISIS_CLV_L1_LSP_HOSTNAME,
217 &ett_isis_lsp_clv_hostname,
218 dissect_lsp_hostname_clv
221 ISIS_CLV_L1_LSP_TE_ROUTER_ID,
222 "Traffic Engineering Router ID",
223 &ett_isis_lsp_clv_te_router_id,
224 dissect_lsp_te_router_id_clv
227 ISIS_CLV_L1_LSP_IP_INTERFACE_ADDR,
228 "IP Interface address(es)",
229 &ett_isis_lsp_clv_ipv4_int_addr,
230 dissect_lsp_ip_int_addr_clv
233 ISIS_CLV_L1_LSP_IPv6_INTERFACE_ADDR,
234 "IPv6 Interface address(es)",
235 &ett_isis_lsp_clv_ipv6_int_addr,
236 dissect_lsp_ipv6_int_addr_clv
239 ISIS_CLV_L1_LSP_AUTHENTICATION_NS,
240 "Authentication(non-spec)",
241 &ett_isis_lsp_clv_auth,
242 dissect_lsp_l1_auth_clv
245 ISIS_CLV_L1_LSP_AUTHENTICATION,
247 &ett_isis_lsp_clv_auth,
248 dissect_lsp_l1_auth_clv
253 &ett_isis_lsp_clv_mt,
257 ISIS_CLV_L1_LSP_MT_IS_REACHABLE,
258 "Multi Topology IS Reachability",
259 &ett_isis_lsp_clv_mt_is,
260 dissect_lsp_mt_is_reachability_clv
271 static const isis_clv_handle_t clv_l2_lsp_opts[] = {
273 ISIS_CLV_L1_LSP_AREA_ADDRESS,
275 &ett_isis_lsp_clv_area_addr,
276 dissect_lsp_area_address_clv
279 ISIS_CLV_L2_LSP_IS_NEIGHBORS,
281 &ett_isis_lsp_clv_is_neighbors,
282 dissect_lsp_l2_is_neighbors_clv
285 ISIS_CLV_L2_LSP_EXT_IS_REACHABLE,
286 "Extended IS reachability",
287 &ett_isis_lsp_clv_ext_is_reachability,
288 dissect_lsp_ext_is_reachability_clv
291 ISIS_CLV_L2_LSP_PARTITION_DIS,
292 "Parition Designated Level 2 IS",
293 &ett_isis_lsp_clv_partition_dis,
294 dissect_lsp_partition_dis_clv
297 ISIS_CLV_L2_LSP_PREFIX_NEIGHBORS,
299 &ett_isis_lsp_clv_prefix_neighbors,
300 dissect_lsp_prefix_neighbors_clv
303 ISIS_CLV_L2_LSP_IP_INT_REACHABLE,
304 "IP Internal reachability",
305 &ett_isis_lsp_clv_ip_reachability,
306 dissect_lsp_ip_reachability_clv
309 ISIS_CLV_L2_LSP_IP_EXT_REACHABLE,
310 "IP External reachability",
311 &ett_isis_lsp_clv_ip_reachability,
312 dissect_lsp_ip_reachability_clv
315 ISIS_CLV_L2_LSP_NLPID,
316 "Protocols supported",
317 &ett_isis_lsp_clv_nlpid,
318 dissect_lsp_nlpid_clv
321 ISIS_CLV_L2_LSP_HOSTNAME,
323 &ett_isis_lsp_clv_hostname,
324 dissect_lsp_hostname_clv
327 ISIS_CLV_L2_LSP_TE_ROUTER_ID,
328 "Traffic Engineering Router ID",
329 &ett_isis_lsp_clv_te_router_id,
330 dissect_lsp_te_router_id_clv
333 ISIS_CLV_L2_LSP_EXT_IP_REACHABLE,
334 "Extended IP Reachability",
335 &ett_isis_lsp_clv_ext_ip_reachability,
336 dissect_lsp_ext_ip_reachability_clv
339 ISIS_CLV_L2_LSP_IPv6_REACHABLE,
341 &ett_isis_lsp_clv_ipv6_reachability,
342 dissect_lsp_ipv6_reachability_clv
345 ISIS_CLV_L2_LSP_IP_INTERFACE_ADDR,
346 "IP Interface address(es)",
347 &ett_isis_lsp_clv_ipv4_int_addr,
348 dissect_lsp_ip_int_addr_clv
351 ISIS_CLV_L2_LSP_IPv6_INTERFACE_ADDR,
352 "IPv6 Interface address(es)",
353 &ett_isis_lsp_clv_ipv6_int_addr,
354 dissect_lsp_ipv6_int_addr_clv
357 ISIS_CLV_L2_LSP_AUTHENTICATION_NS,
358 "Authentication(non spec)",
359 &ett_isis_lsp_clv_auth,
360 dissect_lsp_l2_auth_clv
363 ISIS_CLV_L2_LSP_AUTHENTICATION,
365 &ett_isis_lsp_clv_auth,
366 dissect_lsp_l2_auth_clv
371 &ett_isis_lsp_clv_mt,
375 ISIS_CLV_L2_LSP_MT_IS_REACHABLE,
376 "Multi Topology IS Reachability",
377 &ett_isis_lsp_clv_mt_is,
378 dissect_lsp_mt_is_reachability_clv
390 * Name: dissect_metric()
393 * Display a metric prefix portion. ISIS has the concept of multple
394 * metric per prefix (default, delay, expense, and error). This
395 * routine assists other dissectors by adding a single one of
396 * these to the display tree..
398 * The 8th(msbit) bit in the metric octet is the "supported" bit. The
399 * "default" support is required, so we support a "force_supported"
400 * flag that tells us that it MUST be zero (zero==supported,
401 * so it really should be a "not supported" in the boolean sense)
402 * and to display a protocol failure accordingly. Notably,
403 * Cisco IOS 12(6) blows this!
404 * The 7th bit must be zero (reserved).
407 * tvbuff_t * : tvbuffer for packet data
408 * packet_info * : info for current packet
409 * proto_tree * : protocol display tree to fill out. May be NULL
410 * int : offset into packet data where we are.
411 * guint8 : value of the metric.
412 * char * : string giving type of the metric.
413 * int : force supported. True is the supported bit MUST be zero.
416 * void, but we will add to proto tree if !NULL.
419 dissect_metric(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
420 int offset, guint8 value, char *pstr, int force_supported )
426 s = ISIS_LSP_CLV_METRIC_SUPPORTED(value);
427 proto_tree_add_text(tree, tvb, offset, 1,
428 "%s Metric: %s%s %s%d:%d", pstr,
429 s ? "Not supported" : "Supported",
430 (s && force_supported) ? "(but is required to be)":"",
431 ISIS_LSP_CLV_METRIC_RESERVED(value) ? "(reserved bit != 0)":"",
432 ISIS_LSP_CLV_METRIC_VALUE(value), value );
436 * Name: dissect_lsp_ip_reachability_clv()
439 * Decode an IP reachability CLV. This can be either internal or
440 * external (the clv format does not change and which type we are
441 * displaying is put there by the dispatcher). All of these
442 * are a metric block followed by an IP addr and mask.
445 * tvbuff_t * : tvbuffer for packet data
446 * packet_info * : info for current packet
447 * proto_tree * : proto tree to build on (may be null)
448 * int : current offset into packet data
449 * int : length of IDs in packet.
450 * int : length of this clv
453 * void, will modify proto_tree if not null.
456 dissect_lsp_ip_reachability_clv(tvbuff_t *tvb,
457 packet_info *pinfo, proto_tree *tree, int offset,
458 int id_length, int length)
461 proto_tree *ntree = NULL;
462 guint32 src, mask, prefix_len;
464 guint32 bitmasks[33] = {
466 0x00000008, 0x0000000c, 0x0000000e, 0x0000000f,
467 0x000000f8, 0x000000fc, 0x000000fe, 0x000000ff,
468 0x000008ff, 0x00000cff, 0x00000eff, 0x00000fff,
469 0x0000f8ff, 0x0000fcff, 0x0000feff, 0x0000ffff,
470 0x0008ffff, 0x000cffff, 0x000effff, 0x000fffff,
471 0x00f8ffff, 0x00fcffff, 0x00feffff, 0x00ffffff,
472 0x08ffffff, 0x0cffffff, 0x0effffff, 0x0fffffff,
473 0xf8ffffff, 0xfcffffff, 0xfeffffff, 0xffffffff
477 while ( length > 0 ) {
479 isis_dissect_unknown(tvb, pinfo, tree, offset,
480 "short IP reachability (%d vs 12)", length );
484 * Gotta build a sub-tree for all our pieces
487 tvb_memcpy(tvb, (guint8 *)&src, offset+4, 4);
488 tvb_memcpy(tvb, (guint8 *)&mask, offset+8, 4);
490 /* find out if the mask matches one of 33 possible prefix lengths */
494 while(prefix_len<=33) {
495 if (bitmasks[prefix_len++]==mask) {
501 /* 34 indicates no match -> must be a discontiguous netmask
502 lets dump the mask, otherwise print the prefix_len */
505 ti = proto_tree_add_text ( tree, tvb, offset, 12,
506 "IPv4 prefix: %s mask %s",
507 ip_to_str((guint8*)&src),
508 ip_to_str((guint8*)&mask));
510 ti = proto_tree_add_text ( tree, tvb, offset, 12,
511 "IPv4 prefix: %s/%d",
512 ip_to_str((guint8*)&src),
516 ntree = proto_item_add_subtree(ti,
517 ett_isis_lsp_clv_ip_reachability);
519 proto_tree_add_text (ntree, tvb, offset, 1,
520 "Default Metric: %d, %s, Distribution: %s",
521 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset)),
522 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset)) ? "External" : "Internal",
523 ISIS_LSP_CLV_METRIC_UPDOWN(tvb_get_guint8(tvb, offset)) ? "down" : "up");
526 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+1))) {
527 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: Not supported");
529 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: %d, %s",
530 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+1)),
531 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+1)) ? "External" : "Internal");
534 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+2))) {
535 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: Not supported");
537 proto_tree_add_text (ntree, tvb, offset+2, 1, "Exense Metric: %d, %s",
538 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+2)),
539 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+2)) ? "External" : "Internal");
542 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+3))) {
543 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: Not supported");
545 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: %d, %s",
546 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+3)),
547 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+3)) ? "External" : "Internal");
556 * Name: dissect_lsp_ext_ip_reachability_clv()
558 * Description: Decode an Extended IP Reachability CLV - code 135.
560 * The extended IP reachability TLV is an extended version
561 * of the IP reachability TLVs (codes 128 and 130). It encodes
562 * the metric as a 32-bit unsigned interger and allows to add
566 * tvbuff_t * : tvbuffer for packet data
567 * packet_info * : info for current packet
568 * proto_tree * : proto tree to build on (may be null)
569 * int : current offset into packet data
570 * int : length of IDs in packet.
571 * int : length of this clv
574 * void, will modify proto_tree if not null.
577 dissect_lsp_ext_ip_reachability_clv(tvbuff_t *tvb,
578 packet_info *pinfo, proto_tree *tree, int offset,
579 int id_length, int length)
581 proto_item *pi = NULL;
582 proto_tree *subtree = NULL;
584 guint8 bit_length, byte_length;
591 memset (prefix, 0, 4);
592 ctrl_info = tvb_get_guint8(tvb, offset+4);
593 bit_length = ctrl_info & 0x3f;
594 byte_length = (bit_length + 7) / 8;
595 tvb_memcpy (tvb, prefix, offset+5, byte_length);
596 pi = proto_tree_add_text (tree, tvb, offset, -1,
597 "IPv4 prefix: %s/%d",
600 subtree = proto_item_add_subtree (pi,
601 ett_isis_lsp_part_of_clv_ext_ip_reachability);
603 proto_tree_add_text (subtree, tvb, offset, 4,
604 "Metric: %d, Distribution: %s", tvb_get_ntohl(tvb, offset), ((ctrl_info & 0x80) == 0) ? "up" : "down" );
606 proto_tree_add_text (subtree, tvb, offset+4, 1,
607 "%s sub-TLVs present",
608 ((ctrl_info & 0x40) == 0) ? "no" : "" );
610 len = 5 + byte_length;
611 if ((ctrl_info & 0x40) != 0)
612 len += 1 + tvb_get_guint8(tvb, offset+len) ;
613 proto_item_set_len (pi, len);
620 * Name: dissect_lsp_ipv6_reachability_clv()
622 * Description: Decode an IPv6 reachability CLV - code 236.
625 * tvbuff_t * : tvbuffer for packet data
626 * packet_info * : info for current packet
627 * proto_tree * : proto tree to build on (may be null)
628 * int : current offset into packet data
629 * int : length of IDs in packet.
630 * int : length of this clv
633 * void, will modify proto_tree if not null.
636 dissect_lsp_ipv6_reachability_clv(tvbuff_t *tvb,
637 packet_info *pinfo, proto_tree *tree, int offset,
638 int id_length, int length)
641 proto_tree *ntree = NULL;
642 guint8 bit_length, byte_length;
643 struct e_in6_addr prefix;
650 memset (prefix.s6_addr, 0, 16);
653 bit_length = tvb_get_guint8(tvb, offset+5);
654 byte_length = (bit_length + 7) / 8;
655 tvb_memcpy (tvb, prefix.s6_addr, offset+6, byte_length);
656 ti = proto_tree_add_text (tree, tvb, offset, -1,
658 ip6_to_str (&prefix),
660 ntree = proto_item_add_subtree (ti, ett_isis_lsp_part_of_clv_ipv6_reachability);
662 metric = tvb_get_ntohl(tvb, offset);
663 proto_tree_add_text (ntree, tvb, offset, 4,
664 "Metric: %d", metric);
666 ctrl_info = tvb_get_guint8(tvb, offset+4);
667 proto_tree_add_text (ntree, tvb, offset+4, 1,
668 "Distribution: %s, %s",
669 ((ctrl_info & 0x80) == 0) ? "up" : "down",
670 ((ctrl_info & 0x40) == 0) ? "internal" : "external" );
672 proto_tree_add_text (ntree, tvb, offset+4, 1,
673 "Reserved bits: 0x%x",
674 (ctrl_info & 0x1f) );
675 proto_tree_add_text (ntree, tvb, offset+4, 1,
677 ((ctrl_info & 0x20) == 0) ? "no" : "yes" );
679 len = 6 + byte_length;
680 if ((ctrl_info & 0x20) != 0)
681 len += 1 + tvb_get_guint8(tvb, offset+len);
682 proto_item_set_len (ti, len);
689 * Name: dissect_lsp_nlpid_clv()
692 * Decode for a lsp packets NLPID clv. Calls into the
696 * tvbuff_t * : tvbuffer for packet data
697 * packet_info * : info for current packet
698 * proto_tree * : proto tree to build on (may be null)
699 * int : current offset into packet data
700 * int : length of IDs in packet.
701 * int : length of this clv
704 * void, will modify proto_tree if not null.
707 dissect_lsp_nlpid_clv(tvbuff_t *tvb,
708 packet_info *pinfo, proto_tree *tree, int offset,
709 int id_length, int length)
711 isis_dissect_nlpid_clv(tvb, pinfo, tree, offset, length);
715 * Name: dissect_lsp_mt_clv()
718 * Decode for a lsp packets Multi Topology clv. Calls into the
722 * u_char * : packet data
723 * int : current offset into packet data
724 * guint : length of this clv
725 * int : length of IDs in packet.
726 * frame_data * : frame data
727 * proto_tree * : proto tree to build on (may be null)
730 * void, will modify proto_tree if not null.
733 dissect_lsp_mt_clv(tvbuff_t *tvb,
734 packet_info *pinfo, proto_tree *tree, int offset,
735 int id_length, int length)
737 isis_dissect_mt_clv(tvb, pinfo, tree, offset, length,
738 hf_isis_lsp_clv_mt );
742 * Name: dissect_lsp_hostname_clv()
745 * Decode for a lsp packets hostname clv. Calls into the
749 * tvbuff_t * : tvbuffer for packet data
750 * packet_info * : info for current packet
751 * proto_tree * : proto tree to build on (may be null)
752 * int : current offset into packet data
753 * int : length of IDs in packet.
754 * int : length of this clv
757 * void, will modify proto_tree if not null.
760 dissect_lsp_hostname_clv(tvbuff_t *tvb,
761 packet_info *pinfo, proto_tree *tree, int offset,
762 int id_length, int length)
764 isis_dissect_hostname_clv(tvb, pinfo, tree, offset, length);
769 * Name: dissect_lsp_te_router_id_clv()
772 * Decode for a lsp packets Traffic Engineering ID clv. Calls into the
776 * tvbuff_t * : tvbuffer for packet data
777 * packet_info * : info for current packet
778 * proto_tree * : proto tree to build on (may be null)
779 * int : current offset into packet data
780 * int : length of IDs in packet.
781 * int : length of this clv
784 * void, will modify proto_tree if not null.
787 dissect_lsp_te_router_id_clv(tvbuff_t *tvb,
788 packet_info *pinfo, proto_tree *tree, int offset,
789 int id_length, int length)
791 isis_dissect_te_router_id_clv(tvb, pinfo, tree, offset, length,
792 hf_isis_lsp_clv_te_router_id );
797 * Name: dissect_lsp_ip_int_addr_clv()
800 * Decode for a lsp packets ip interface addr clv. Calls into the
804 * tvbuff_t * : tvbuffer for packet data
805 * packet_info * : info for current packet
806 * proto_tree * : proto tree to build on (may be null)
807 * int : current offset into packet data
808 * int : length of IDs in packet.
809 * int : length of this clv
812 * void, will modify proto_tree if not null.
815 dissect_lsp_ip_int_addr_clv(tvbuff_t *tvb,
816 packet_info *pinfo, proto_tree *tree, int offset,
817 int id_length, int length)
819 isis_dissect_ip_int_clv(tvb, pinfo, tree, offset, length,
820 hf_isis_lsp_clv_ipv4_int_addr );
824 * Name: dissect_lsp_ipv6_int_addr_clv()
826 * Description: Decode an IPv6 interface addr CLV - code 232.
828 * Calls into the clv common one.
831 * tvbuff_t * : tvbuffer for packet data
832 * packet_info * : info for current packet
833 * proto_tree * : proto tree to build on (may be null)
834 * int : current offset into packet data
835 * int : length of IDs in packet.
836 * int : length of this clv
839 * void, will modify proto_tree if not null.
842 dissect_lsp_ipv6_int_addr_clv(tvbuff_t *tvb,
843 packet_info *pinfo, proto_tree *tree, int offset,
844 int id_length, int length)
846 isis_dissect_ipv6_int_clv(tvb, pinfo, tree, offset, length,
847 hf_isis_lsp_clv_ipv6_int_addr );
851 * Name: dissect_lsp_L1_auth_clv()
854 * Decode for a lsp packets authenticaion clv. Calls into the
855 * clv common one. An auth inside a L1 LSP is a per area password
858 * tvbuff_t * : tvbuffer for packet data
859 * packet_info * : info for current packet
860 * proto_tree * : proto tree to build on (may be null)
861 * int : current offset into packet data
862 * int : length of IDs in packet.
863 * int : length of this clv
866 * void, will modify proto_tree if not null.
869 dissect_lsp_l1_auth_clv(tvbuff_t *tvb,
870 packet_info *pinfo, proto_tree *tree, int offset,
871 int id_length, int length)
873 isis_dissect_authentication_clv(tvb, pinfo, tree, offset, length,
874 "Per area authentication" );
878 * Name: dissect_lsp_L2_auth_clv()
881 * Decode for a lsp packets authenticaion clv. Calls into the
882 * clv common one. An auth inside a L2 LSP is a per domain password
885 * tvbuff_t * : tvbuffer for packet data
886 * packet_info * : info for current packet
887 * proto_tree * : proto tree to build on (may be null)
888 * int : current offset into packet data
889 * int : length of IDs in packet.
890 * int : length of this clv
893 * void, will modify proto_tree if not null.
896 dissect_lsp_l2_auth_clv(tvbuff_t *tvb,
897 packet_info *pinfo, proto_tree *tree, int offset,
898 int id_length, int length)
900 isis_dissect_authentication_clv(tvb, pinfo, tree, offset, length,
901 "Per domain authentication" );
905 * Name: dissect_lsp_area_address_clv()
908 * Decode for a lsp packet's area address clv. Call into clv common
912 * tvbuff_t * : tvbuffer for packet data
913 * packet_info * : info for current packet
914 * proto_tree * : protocol display tree to fill out. May be NULL
915 * int : offset into packet data where we are.
916 * int : length of IDs in packet.
917 * int : length of clv we are decoding
920 * void, but we will add to proto tree if !NULL.
923 dissect_lsp_area_address_clv(tvbuff_t *tvb,
924 packet_info *pinfo, proto_tree *tree, int offset,
925 int id_length, int length)
927 isis_dissect_area_address_clv(tvb, pinfo, tree, offset, length);
931 * Name: dissect_lsp_eis_neighbors_clv_inner()
934 * Real work horse for showing neighbors. This means we decode the
935 * first octet as either virtual/!virtual (if show_virtual param is
936 * set), or as a must == 0 reserved value.
938 * Once past that, we decode n neighbor elements. Each neighbor
939 * is comprised of a metric block (is dissect_metric) and the
943 * tvbuff_t * : tvbuffer for packet data
944 * packet_info * : info for current packet
945 * proto_tree * : protocol display tree to fill out. May be NULL
946 * int : offset into packet data where we are.
947 * int : length of IDs in packet.
948 * int : length of clv we are decoding
949 * int : set to decode first octet as virtual vs reserved == 0
950 * int : set to indicate EIS instead of IS (6 octet per addr instead of 7)
953 * void, but we will add to proto tree if !NULL.
956 dissect_lsp_eis_neighbors_clv_inner(tvbuff_t *tvb, packet_info *pinfo,
957 proto_tree *tree, int offset,
958 int length, int id_length, int show_virtual, int is_eis)
961 proto_tree *ntree = NULL;
965 id_length++; /* IDs are one octet longer in IS neighbours */
967 if ( show_virtual ) {
968 /* virtual path flag */
969 proto_tree_add_text ( tree, tvb, offset, 1,
970 tvb_get_guint8(tvb, offset) ? "IsNotVirtual" : "IsVirtual" );
972 proto_tree_add_text ( tree, tvb, offset, 1,
973 "Reserved value 0x%02x, must == 0",
974 tvb_get_guint8(tvb, offset) );
980 tlen = 4 + id_length;
982 while ( length > 0 ) {
984 isis_dissect_unknown(tvb, pinfo, tree, offset,
985 "short E/IS reachability (%d vs %d)", length,
990 * Gotta build a sub-tree for all our pieces
994 ti = proto_tree_add_text(tree, tvb, offset, tlen,
996 print_system_id( tvb_get_ptr(tvb, offset+4, id_length), id_length ) );
998 ti = proto_tree_add_text(tree, tvb, offset, tlen,
1000 print_system_id(tvb_get_ptr(tvb, offset+4, id_length), id_length ) );
1002 ntree = proto_item_add_subtree(ti,
1003 ett_isis_lsp_clv_is_neighbors);
1007 proto_tree_add_text (ntree, tvb, offset, 1,
1008 "Default Metric: %d, %s",
1009 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset)),
1010 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset)) ? "External" : "Internal");
1012 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+1))) {
1013 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: Not supported");
1015 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: %d, %s",
1016 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+1)),
1017 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+1)) ? "External" : "Internal");
1021 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+2))) {
1022 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: Not supported");
1024 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: %d, %s",
1025 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+2)),
1026 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+2)) ? "External" : "Internal");
1029 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+3))) {
1030 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: Not supported");
1032 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: %d, %s",
1033 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+3)),
1034 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+3)) ? "External" : "Internal");
1044 * Name: dissect_lsp_l1_is_neighbors_clv()
1047 * Dispatch a l1 intermediate system neighbor by calling
1048 * the inner function with show virtual set to TRUE and is es set to FALSE.
1051 * tvbuff_t * : tvbuffer for packet data
1052 * packet_info * : info for current packet
1053 * proto_tree * : protocol display tree to fill out. May be NULL
1054 * int : offset into packet data where we are.
1055 * int : length of IDs in packet.
1056 * int : length of clv we are decoding
1059 * void, but we will add to proto tree if !NULL.
1062 dissect_lsp_l1_is_neighbors_clv(tvbuff_t *tvb,
1063 packet_info *pinfo, proto_tree *tree, int offset,
1064 int id_length, int length)
1066 dissect_lsp_eis_neighbors_clv_inner(tvb, pinfo, tree, offset,
1067 length, id_length, TRUE, FALSE);
1071 * Name: dissect_lsp_l1_es_neighbors_clv()
1074 * Dispatch a l1 end or intermediate system neighbor by calling
1075 * the inner function with show virtual set to TRUE and es set to TRUE.
1078 * tvbuff_t * : tvbuffer for packet data
1079 * packet_info * : info for current packet
1080 * proto_tree * : protocol display tree to fill out. May be NULL
1081 * int : offset into packet data where we are.
1082 * int : length of IDs in packet.
1083 * int : length of clv we are decoding
1086 * void, but we will add to proto tree if !NULL.
1089 dissect_lsp_l1_es_neighbors_clv(tvbuff_t *tvb,
1090 packet_info *pinfo, proto_tree *tree, int offset,
1091 int id_length, int length)
1093 dissect_lsp_eis_neighbors_clv_inner(tvb, pinfo, tree, offset,
1094 length, id_length, TRUE, TRUE);
1098 * Name: dissect_lsp_l2_is_neighbors_clv()
1101 * Dispatch a l2 intermediate system neighbor by calling
1102 * the inner function with show virtual set to FALSE, and is es set
1106 * tvbuff_t * : tvbuffer for packet data
1107 * packet_info * : info for current packet
1108 * proto_tree * : protocol display tree to fill out. May be NULL
1109 * int : offset into packet data where we are.
1110 * int : length of IDs in packet.
1111 * int : length of clv we are decoding
1114 * void, but we will add to proto tree if !NULL.
1117 dissect_lsp_l2_is_neighbors_clv(tvbuff_t *tvb,
1118 packet_info *pinfo, proto_tree *tree, int offset,
1119 int id_length, int length)
1121 dissect_lsp_eis_neighbors_clv_inner(tvb, pinfo, tree, offset,
1122 length, id_length, FALSE, FALSE);
1127 * Name: dissect_subclv_admin_group ()
1129 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1131 * This function is called by dissect_lsp_ext_is_reachability_clv()
1132 * for dissect the administrive group sub-CLV (code 3).
1135 * tvbuff_t * : tvbuffer for packet data
1136 * packet_info * : info for current packet
1137 * proto_tree * : protocol display tree to fill out.
1138 * int : offset into packet data where we are (beginning of the sub_clv value).
1144 dissect_subclv_admin_group (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset) {
1151 ti = proto_tree_add_text(tree, tvb, offset-2, 6, "Administrative group(s):");
1152 ntree = proto_item_add_subtree (ti, ett_isis_lsp_subclv_admin_group);
1154 clv_value = tvb_get_ntohl(tvb, offset);
1156 for (i = 0 ; i < 32 ; i++) {
1157 if ( (clv_value & mask) != 0 ) {
1158 proto_tree_add_text (ntree, tvb, offset, 4, "group %d", i);
1165 * Name: dissect_subclv_max_bw ()
1167 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1169 * This function is called by dissect_lsp_ext_is_reachability_clv()
1170 * for dissect the maximum link bandwidth sub-CLV (code 9).
1173 * u_char * : packet data
1174 * int : offset into packet data where we are (beginning of the sub_clv value).
1175 * proto_tree * : protocol display tree to fill out.
1181 dissect_subclv_max_bw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1186 ui = tvb_get_ntohl(tvb, offset);
1187 memcpy (&bw, &ui, 4);
1188 proto_tree_add_text (tree, tvb, offset-2, 6,
1189 "Maximum link bandwidth : %.2f Mbps", bw*8/1000000 );
1193 * Name: dissect_subclv_rsv_bw ()
1195 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1197 * This function is called by dissect_lsp_ext_is_reachability_clv()
1198 * for dissect the reservable link bandwidth sub-CLV (code 10).
1201 * u_char * : packet data
1202 * int : offset into packet data where we are (beginning of the sub_clv value).
1203 * proto_tree * : protocol display tree to fill out.
1209 dissect_subclv_rsv_bw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1214 ui = tvb_get_ntohl(tvb, offset);
1215 memcpy (&bw, &ui, 4);
1216 proto_tree_add_text (tree, tvb, offset-2, 6,
1217 "Reservable link bandwidth: %.2f Mbps", bw*8/1000000 );
1221 * Name: dissect_subclv_unrsv_bw ()
1223 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1225 * This function is called by dissect_lsp_ext_is_reachability_clv()
1226 * for dissect the unreserved bandwidth sub-CLV (code 11).
1229 * u_char * : packet data
1230 * int : offset into packet data where we are (beginning of the sub_clv value).
1231 * proto_tree * : protocol display tree to fill out.
1237 dissect_subclv_unrsv_bw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1245 ti = proto_tree_add_text (tree, tvb, offset-2, 34, "Unreserved bandwidth:");
1246 ntree = proto_item_add_subtree (ti, ett_isis_lsp_subclv_unrsv_bw);
1248 for (i = 0 ; i < 8 ; i++) {
1249 ui = tvb_get_ntohl(tvb, offset);;
1250 memcpy (&bw, &ui, 4);
1251 proto_tree_add_text (ntree, tvb, offset+4*i, 4,
1252 "priority level %d: %.2f Mbps", i, bw*8/1000000 );
1257 * Name: dissect_lsp_ext_is_reachability_clv()
1259 * Description: Decode a Extended IS Reachability CLV - code 22
1261 * The extended IS reachability TLV is an extended version
1262 * of the IS reachability TLV (code 2). It encodes the metric
1263 * as a 24-bit unsigned interger and allows to add sub-CLV(s).
1266 * tvbuff_t * : tvbuffer for packet data
1267 * packet_info * : info for current packet
1268 * proto_tree * : protocol display tree to fill out. May be NULL
1269 * int : offset into packet data where we are.
1270 * int : length of IDs in packet.
1271 * int : length of clv we are decoding
1274 * void, but we will add to proto tree if !NULL.
1277 dissect_lsp_ext_is_reachability_clv(tvbuff_t *tvb,
1278 packet_info *pinfo, proto_tree *tree, int offset,
1279 int id_length, int length)
1282 proto_tree *ntree = NULL;
1285 guint8 clv_code, clv_len;
1289 while (length > 0) {
1290 ti = proto_tree_add_text (tree, tvb, offset, -1,
1292 print_system_id (tvb_get_ptr(tvb, offset, 7), 7) );
1293 ntree = proto_item_add_subtree (ti,
1294 ett_isis_lsp_part_of_clv_ext_is_reachability );
1296 proto_tree_add_text (ntree, tvb, offset+7, 3,
1297 "Metric: %d", tvb_get_ntoh24(tvb, offset+7) );
1299 subclvs_len = tvb_get_guint8(tvb, offset+10);
1300 if (subclvs_len == 0) {
1301 proto_tree_add_text (ntree, tvb, offset+10, 1, "no sub-TLVs present");
1305 while (i < subclvs_len) {
1306 clv_code = tvb_get_guint8(tvb, offset+11+i);
1307 clv_len = tvb_get_guint8(tvb, offset+12+i);
1310 dissect_subclv_admin_group(tvb, pinfo, ntree, offset+13+i);
1313 proto_tree_add_text (ntree, tvb, offset+11+i, 6,
1314 "IPv4 interface address: %s", ip_to_str (tvb_get_ptr(tvb, offset+13+i, 4)) );
1317 proto_tree_add_text (ntree, tvb, offset+11+i, 6,
1318 "IPv4 neighbor address: %s", ip_to_str (tvb_get_ptr(tvb, offset+13+i, 4)) );
1321 dissect_subclv_max_bw (tvb, pinfo, ntree, offset+13+i);
1324 dissect_subclv_rsv_bw (tvb, pinfo, ntree, offset+13+i);
1327 dissect_subclv_unrsv_bw (tvb, pinfo, ntree, offset+13+i);
1330 proto_tree_add_text (ntree, tvb, offset+11+i, 5,
1331 "Traffic engineering default metric: %d",
1332 tvb_get_ntoh24(tvb, offset+13+i) );
1339 proto_tree_add_text (ntree, tvb, offset+11+i, clv_len+2,
1340 "Unknown Cisco specific extensions: code %d, length %d",
1341 clv_code, clv_len );
1344 proto_tree_add_text (ntree, tvb, offset+11+i, clv_len+2,
1345 "Unknown sub-CLV: code %d, length %d", clv_code, clv_len );
1352 len = 11 + subclvs_len;
1353 proto_item_set_len (ti, len);
1364 static void dissect_lsp_mt_is_reachability_clv(tvbuff_t *tvb,
1365 packet_info *pinfo, proto_tree *tree, int offset,
1366 int id_length, int length)
1369 proto_tree *ntree = NULL;
1378 while (length > 0) {
1380 /* fetch two bytes */
1381 mt_block = tvb_get_ntohs(tvb, offset);
1383 /* mask out the lower 12 bits */
1384 switch(mt_block&0x0fff) {
1386 strcpy(mt_desc,"IPv4 unicast");
1389 strcpy(mt_desc,"In-Band Management");
1392 strcpy(mt_desc,"IPv6 unicast");
1395 strcpy(mt_desc,"Multicast");
1398 strcpy(mt_desc,"Development, Experimental or Proprietary");
1401 strcpy(mt_desc,"Reserved for IETF Consensus");
1404 proto_tree_add_text ( tree, tvb, offset, 2 ,
1405 "%s Topology (0x%x)",
1409 ti = proto_tree_add_text (tree, tvb, offset+2, -1,
1411 print_system_id(tvb_get_ptr(tvb, offset+2, 7), 7) );
1413 ntree = proto_item_add_subtree (ti,
1414 ett_isis_lsp_part_of_clv_mt_is );
1416 proto_tree_add_text (ntree, tvb, offset+9, 3,
1417 "Metric: %d", tvb_get_ntoh24(tvb, offset+9) );
1419 subclvs_len = tvb_get_guint8(tvb, offset+12);
1420 if (subclvs_len == 0) {
1421 proto_tree_add_text (ntree, tvb, offset+12, 1, "no sub-TLVs present");
1423 proto_tree_add_text (ntree, tvb, offset+12, 1, "sub-TLVs present");
1426 len = 13 + subclvs_len;
1427 proto_item_set_len (ti, len);
1435 * Name: dissect_lsp_partition_dis_clv()
1438 * This CLV is used to indicate which system is the designated
1439 * IS for partition repair. This means just putting out the
1440 * "id_length"-octet IS.
1443 * tvbuff_t * : tvbuffer for packet data
1444 * packet_info * : info for current packet
1445 * proto_tree * : protocol display tree to fill out. May be NULL
1446 * int : offset into packet data where we are.
1447 * int : length of IDs in packet.
1448 * int : length of clv we are decoding
1451 * void, but we will add to proto tree if !NULL.
1454 dissect_lsp_partition_dis_clv(tvbuff_t *tvb,
1455 packet_info *pinfo, proto_tree *tree, int offset,
1456 int id_length, int length)
1458 if ( length < id_length ) {
1459 isis_dissect_unknown(tvb, pinfo, tree, offset,
1460 "short lsp parition DIS(%d vs %d)", length,
1465 * Gotta build a sub-tree for all our pieces
1468 proto_tree_add_text ( tree, tvb, offset, id_length,
1469 "Partition designated L2 IS: %s",
1470 print_system_id( tvb_get_ptr(tvb, offset, id_length), id_length ) );
1472 length -= id_length;
1473 offset += id_length;
1475 isis_dissect_unknown(tvb, pinfo, tree, offset,
1476 "Long lsp parition DIS, %d left over", length );
1482 * Name: dissect_lsp_prefix_neighbors_clv()
1485 * The prefix CLV describes what other (OSI) networks we can reach
1486 * and what their cost is. It is built from a metric block
1487 * (see dissect_metric) followed by n addresses.
1490 * tvbuff_t * : tvbuffer for packet data
1491 * packet_info * : info for current packet
1492 * proto_tree * : protocol display tree to fill out. May be NULL
1493 * int : offset into packet data where we are.
1494 * int : length of IDs in packet.
1495 * int : length of clv we are decoding
1498 * void, but we will add to proto tree if !NULL.
1501 dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb,
1502 packet_info *pinfo, proto_tree *tree, int offset,
1503 int id_length, int length)
1509 isis_dissect_unknown(tvb, pinfo, tree, offset,
1510 "Short lsp prefix neighbors (%d vs 4)", length );
1514 dissect_metric (tvb, pinfo, tree, offset,
1515 tvb_get_guint8(tvb, offset), "Default", TRUE );
1516 dissect_metric (tvb, pinfo, tree, offset+1,
1517 tvb_get_guint8(tvb, offset+1), "Delay", FALSE );
1518 dissect_metric (tvb, pinfo, tree, offset+2,
1519 tvb_get_guint8(tvb, offset+2), "Expense", FALSE );
1520 dissect_metric (tvb, pinfo, tree, offset+3,
1521 tvb_get_guint8(tvb, offset+3), "Error", FALSE );
1525 while ( length > 0 ) {
1526 mylen = tvb_get_guint8(tvb, offset);
1529 isis_dissect_unknown(tvb, pinfo, tree, offset,
1530 "Zero payload space after length in prefix neighbor" );
1533 if ( mylen > length) {
1534 isis_dissect_unknown(tvb, pinfo, tree, offset,
1535 "Interal length of prefix neighbor too long (%d vs %d)",
1541 * Lets turn the area address into "standard" 0000.0000.etc
1544 sbuf = print_area( tvb_get_ptr(tvb, offset+1, mylen), mylen );
1545 /* and spit it out */
1547 proto_tree_add_text ( tree, tvb, offset, mylen + 1,
1548 "Area address (%d): %s", mylen, sbuf );
1550 offset += mylen + 1;
1551 length -= mylen; /* length already adjusted for len fld*/
1556 * Name: isis_lsp_decode_lsp_id()
1559 * Display a LSP id into the display tree.
1562 * tvbuff_t * : tvbuffer for packet data
1563 * packet_info * : info for current packet
1564 * proto_tree * : tree to display into. REQUIRED
1565 * int : offset into packet data where we are.
1566 * char * : title string
1567 * int : length of IDs in packet.
1570 * void, but we will add to proto tree
1573 isis_lsp_decode_lsp_id(tvbuff_t *tvb, packet_info *pinfo,
1574 proto_tree *tree, int offset, char *tstr, int id_length)
1576 proto_tree_add_text(tree, tvb, offset, id_length + 2,
1577 "%s: %s.%02x-%02x", tstr,
1578 print_system_id( tvb_get_ptr(tvb, offset, id_length), id_length ),
1579 tvb_get_guint8(tvb, offset+id_length),
1580 tvb_get_guint8(tvb, offset+id_length+1) );
1584 * Name: isis_dissect_isis_lsp()
1587 * Print out the LSP part of the main header and then call the CLV
1588 * de-mangler with the right list of valid CLVs.
1591 * tvbuff_t * : tvbuffer for packet data
1592 * packet_info * : info for current packet
1593 * proto_tree * : protocol display tree to add to. May be NULL.
1594 * int offset : our offset into packet data.
1595 * int : LSP type, a la packet-isis.h ISIS_TYPE_* values
1596 * int : header length of packet.
1597 * int : length of IDs in packet.
1600 * void, but we will add to proto tree if !NULL.
1603 isis_dissect_isis_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1604 int offset, int lsp_type, int header_length, int id_length)
1607 proto_tree *lsp_tree = NULL;
1610 int inx, q, some, value, len;
1613 ti = proto_tree_add_text(tree, tvb, offset, -1,
1615 lsp_tree = proto_item_add_subtree(ti, ett_isis_lsp);
1618 pdu_length = tvb_get_ntohs(tvb, offset);
1620 proto_tree_add_uint(lsp_tree, hf_isis_lsp_pdu_length, tvb,
1621 offset, 2, pdu_length);
1626 proto_tree_add_uint(lsp_tree, hf_isis_lsp_remaining_life, tvb,
1627 offset, 2, tvb_get_ntohs(tvb, offset));
1632 isis_lsp_decode_lsp_id(tvb, pinfo, lsp_tree, offset,
1633 "LSP ID", id_length);
1635 offset += id_length + 2;
1638 proto_tree_add_uint(lsp_tree, hf_isis_lsp_sequence_number, tvb,
1640 tvb_get_ntohl(tvb, offset));
1645 /* XXX -> we could validate the cksum here! */
1646 proto_tree_add_uint(lsp_tree, hf_isis_lsp_checksum, tvb,
1647 offset, 2, tvb_get_ntohs(tvb, offset));
1653 * We need to build our type block values.
1657 value = ISIS_LSP_ATT(tvb_get_guint8(tvb, offset));
1659 for ( q = (1<<ISIS_LSP_ATT_SHIFT); q > 0; q = q >> 1 ){
1664 strcat ( sbuf, isis_lsp_attached_bits[inx] );
1669 strcat ( sbuf, "default-only" );
1671 proto_tree_add_text(lsp_tree, tvb, offset + 18, 1,
1672 "Type block(0x%02x): P:%d, Supported metric(s): %s, OL:%d, istype:%s",
1673 tvb_get_guint8(tvb, offset),
1674 ISIS_LSP_PARTITION(tvb_get_guint8(tvb, offset)) ? 1 : 0,
1676 ISIS_LSP_HIPPITY(tvb_get_guint8(tvb, offset)) ? 1 : 0,
1677 val_to_str(ISIS_LSP_IS_TYPE(tvb_get_guint8(tvb, offset)),
1678 isis_lsp_istype_vals, "Unknown (0x%x)")
1683 len = pdu_length - header_length;
1685 isis_dissect_unknown(tvb, pinfo, tree, offset,
1686 "packet header length %d went beyond packet",
1691 * Now, we need to decode our CLVs. We need to pass in
1692 * our list of valid ones!
1694 if (lsp_type == ISIS_TYPE_L1_LSP){
1695 isis_dissect_clvs(tvb, pinfo, lsp_tree, offset,
1696 clv_l1_lsp_opts, len, id_length,
1697 ett_isis_lsp_clv_unknown );
1699 isis_dissect_clvs(tvb, pinfo, lsp_tree, offset,
1700 clv_l2_lsp_opts, len, id_length,
1701 ett_isis_lsp_clv_unknown );
1705 * Name: isis_register_lsp()
1708 * Register our protocol sub-sets with protocol manager.
1711 * int : protocol index for the ISIS protocol
1717 isis_register_lsp(int proto_isis) {
1718 static hf_register_info hf[] = {
1719 { &hf_isis_lsp_pdu_length,
1720 { "PDU length", "isis.lsp.pdu_length", FT_UINT16,
1721 BASE_DEC, NULL, 0x0, "", HFILL }},
1723 { &hf_isis_lsp_remaining_life,
1724 { "Remaining lifetime", "isis.lsp.remaining_life", FT_UINT16,
1725 BASE_DEC, NULL, 0x0, "", HFILL }},
1727 { &hf_isis_lsp_sequence_number,
1728 { "Sequence number", "isis.lsp.sequence_number",
1729 FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1731 { &hf_isis_lsp_checksum,
1732 { "Checksum", "isis.lsp.checksum",FT_UINT16,
1733 BASE_HEX, NULL, 0x0, "", HFILL }},
1735 { &hf_isis_lsp_clv_ipv4_int_addr,
1736 { "IPv4 interface address", "isis.lsp.clv_ipv4_int_addr", FT_IPv4,
1737 BASE_NONE, NULL, 0x0, "", HFILL }},
1739 { &hf_isis_lsp_clv_ipv6_int_addr,
1740 { "IPv6 interface address", "isis.lsp.clv_ipv6_int_addr", FT_IPv6,
1741 BASE_NONE, NULL, 0x0, "", HFILL }},
1743 { &hf_isis_lsp_clv_te_router_id,
1744 { "Traffic Engineering Router ID", "isis.lsp.clv_te_router_id", FT_IPv4,
1745 BASE_NONE, NULL, 0x0, "", HFILL }},
1747 static gint *ett[] = {
1749 &ett_isis_lsp_clv_area_addr,
1750 &ett_isis_lsp_clv_is_neighbors,
1751 &ett_isis_lsp_clv_ext_is_reachability, /* CLV 22 */
1752 &ett_isis_lsp_part_of_clv_ext_is_reachability,
1753 &ett_isis_lsp_subclv_admin_group,
1754 &ett_isis_lsp_subclv_unrsv_bw,
1755 &ett_isis_lsp_clv_unknown,
1756 &ett_isis_lsp_clv_partition_dis,
1757 &ett_isis_lsp_clv_prefix_neighbors,
1758 &ett_isis_lsp_clv_auth,
1759 &ett_isis_lsp_clv_nlpid,
1760 &ett_isis_lsp_clv_hostname,
1761 &ett_isis_lsp_clv_ipv4_int_addr,
1762 &ett_isis_lsp_clv_ipv6_int_addr, /* CLV 232 */
1763 &ett_isis_lsp_clv_te_router_id,
1764 &ett_isis_lsp_clv_ip_reachability,
1765 &ett_isis_lsp_clv_ext_ip_reachability, /* CLV 135 */
1766 &ett_isis_lsp_part_of_clv_ext_ip_reachability,
1767 &ett_isis_lsp_clv_ipv6_reachability, /* CLV 236 */
1768 &ett_isis_lsp_part_of_clv_ipv6_reachability,
1769 &ett_isis_lsp_clv_mt,
1770 &ett_isis_lsp_clv_mt_is,
1771 &ett_isis_lsp_part_of_clv_mt_is,
1774 proto_register_field_array(proto_isis, hf, array_length(hf));
1775 proto_register_subtree_array(ett, array_length(ett));