2 * Routines for decoding isis lsp packets and their CLVs
4 * $Id: packet-isis-lsp.c,v 1.18 2001/06/23 19:45:12 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_area_address_clv(const u_char *pd, int offset,
103 guint length, int id_length, frame_data *fd, proto_tree *tree);
104 static void dissect_lsp_l1_is_neighbors_clv(const u_char *pd, int offset,
105 guint length, int id_length, frame_data *fd, proto_tree *tree);
106 static void dissect_lsp_l1_es_neighbors_clv(const u_char *pd, int offset,
107 guint length, int id_length, frame_data *fd, proto_tree *tree);
108 static void dissect_lsp_l2_is_neighbors_clv(const u_char *pd, int offset,
109 guint length, int id_length, frame_data *fd, proto_tree *tree);
110 static void dissect_lsp_ext_is_reachability_clv(const u_char *pd, int offset,
111 guint length, int id_length, frame_data *fd, proto_tree *tree);
112 static void dissect_lsp_partition_dis_clv(const u_char *pd, int offset,
113 guint length, int id_length, frame_data *fd, proto_tree *tree);
114 static void dissect_lsp_prefix_neighbors_clv(const u_char *pd, int offset,
115 guint length, int id_length, frame_data *fd, proto_tree *tree);
116 static void dissect_lsp_ip_reachability_clv(const u_char *pd, int offset,
117 guint length, int id_length, frame_data *fd, proto_tree *tree);
118 static void dissect_lsp_ext_ip_reachability_clv(const u_char *pd, int offset,
119 guint length, int id_length, frame_data *fd, proto_tree *tree);
120 static void dissect_lsp_ipv6_reachability_clv(const u_char *pd, int offset,
121 guint length, int id_length, frame_data *fd, proto_tree *tree);
122 static void dissect_lsp_nlpid_clv(const u_char *pd, int offset,
123 guint length, int id_length, frame_data *fd, proto_tree *tree);
124 static void dissect_lsp_hostname_clv(const u_char *pd, int offset,
125 guint length, int id_length, frame_data *fd, proto_tree *tree);
126 static void dissect_lsp_te_router_id_clv(const u_char *pd, int offset,
127 guint length, int id_length, frame_data *fd, proto_tree *tree);
128 static void dissect_lsp_ip_int_addr_clv(const u_char *pd, int offset,
129 guint length, int id_length, frame_data *fd, proto_tree *tree);
130 static void dissect_lsp_ipv6_int_addr_clv(const u_char *pd, int offset,
131 guint length, int id_length, frame_data *fd, proto_tree *tree);
132 static void dissect_lsp_l1_auth_clv(const u_char *pd, int offset,
133 guint length, int id_length, frame_data *fd, proto_tree *tree);
134 static void dissect_lsp_l2_auth_clv(const u_char *pd, int offset,
135 guint length, int id_length, frame_data *fd, proto_tree *tree);
136 static void dissect_lsp_mt_clv(const u_char *pd, int offset,
137 guint length, int id_length, frame_data *fd, proto_tree *tree);
138 static void dissect_lsp_mt_is_reachability_clv(const u_char *pd, int offset,
139 guint length, int id_length, frame_data *fd, proto_tree *tree);
141 static const isis_clv_handle_t clv_l1_lsp_opts[] = {
143 ISIS_CLV_L1_LSP_AREA_ADDRESS,
145 &ett_isis_lsp_clv_area_addr,
146 dissect_lsp_area_address_clv
149 ISIS_CLV_L1_LSP_IS_NEIGHBORS,
151 &ett_isis_lsp_clv_is_neighbors,
152 dissect_lsp_l1_is_neighbors_clv
155 ISIS_CLV_L1_LSP_ES_NEIGHBORS,
157 &ett_isis_lsp_clv_is_neighbors,
158 dissect_lsp_l1_es_neighbors_clv
161 ISIS_CLV_L1_LSP_EXT_IS_REACHABLE,
162 "Extended IS reachability",
163 &ett_isis_lsp_clv_ext_is_reachability,
164 dissect_lsp_ext_is_reachability_clv
167 ISIS_CLV_L1_LSP_IP_INT_REACHABLE,
168 "IP Internal reachability",
169 &ett_isis_lsp_clv_ip_reachability,
170 dissect_lsp_ip_reachability_clv
173 ISIS_CLV_L1_LSP_IP_EXT_REACHABLE,
174 "IP External reachability",
175 &ett_isis_lsp_clv_ip_reachability,
176 dissect_lsp_ip_reachability_clv
179 ISIS_CLV_L1_LSP_EXT_IP_REACHABLE,
180 "Extended IP Reachability",
181 &ett_isis_lsp_clv_ext_ip_reachability,
182 dissect_lsp_ext_ip_reachability_clv
185 ISIS_CLV_L1_LSP_IPv6_REACHABLE,
187 &ett_isis_lsp_clv_ipv6_reachability,
188 dissect_lsp_ipv6_reachability_clv
191 ISIS_CLV_L1_LSP_NLPID,
192 "Protocols supported",
193 &ett_isis_lsp_clv_nlpid,
194 dissect_lsp_nlpid_clv
197 ISIS_CLV_L1_LSP_HOSTNAME,
199 &ett_isis_lsp_clv_hostname,
200 dissect_lsp_hostname_clv
203 ISIS_CLV_L1_LSP_TE_ROUTER_ID,
204 "Traffic Engineering Router ID",
205 &ett_isis_lsp_clv_te_router_id,
206 dissect_lsp_te_router_id_clv
209 ISIS_CLV_L1_LSP_IP_INTERFACE_ADDR,
210 "IP Interface address(es)",
211 &ett_isis_lsp_clv_ipv4_int_addr,
212 dissect_lsp_ip_int_addr_clv
215 ISIS_CLV_L1_LSP_IPv6_INTERFACE_ADDR,
216 "IPv6 Interface address(es)",
217 &ett_isis_lsp_clv_ipv6_int_addr,
218 dissect_lsp_ipv6_int_addr_clv
221 ISIS_CLV_L1_LSP_AUTHENTICATION_NS,
222 "Authentication(non-spec)",
223 &ett_isis_lsp_clv_auth,
224 dissect_lsp_l1_auth_clv
227 ISIS_CLV_L1_LSP_AUTHENTICATION,
229 &ett_isis_lsp_clv_auth,
230 dissect_lsp_l1_auth_clv
235 &ett_isis_lsp_clv_mt,
239 ISIS_CLV_L1_LSP_MT_IS_REACHABLE,
240 "Multi Topology IS Reachability",
241 &ett_isis_lsp_clv_mt_is,
242 dissect_lsp_mt_is_reachability_clv
253 static const isis_clv_handle_t clv_l2_lsp_opts[] = {
255 ISIS_CLV_L1_LSP_AREA_ADDRESS,
257 &ett_isis_lsp_clv_area_addr,
258 dissect_lsp_area_address_clv
261 ISIS_CLV_L2_LSP_IS_NEIGHBORS,
263 &ett_isis_lsp_clv_is_neighbors,
264 dissect_lsp_l2_is_neighbors_clv
267 ISIS_CLV_L2_LSP_EXT_IS_REACHABLE,
268 "Extended IS reachability",
269 &ett_isis_lsp_clv_ext_is_reachability,
270 dissect_lsp_ext_is_reachability_clv
273 ISIS_CLV_L2_LSP_PARTITION_DIS,
274 "Parition Designated Level 2 IS",
275 &ett_isis_lsp_clv_partition_dis,
276 dissect_lsp_partition_dis_clv
279 ISIS_CLV_L2_LSP_PREFIX_NEIGHBORS,
281 &ett_isis_lsp_clv_prefix_neighbors,
282 dissect_lsp_prefix_neighbors_clv
285 ISIS_CLV_L2_LSP_IP_INT_REACHABLE,
286 "IP Internal reachability",
287 &ett_isis_lsp_clv_ip_reachability,
288 dissect_lsp_ip_reachability_clv
291 ISIS_CLV_L2_LSP_IP_EXT_REACHABLE,
292 "IP External reachability",
293 &ett_isis_lsp_clv_ip_reachability,
294 dissect_lsp_ip_reachability_clv
297 ISIS_CLV_L2_LSP_NLPID,
298 "Protocols supported",
299 &ett_isis_lsp_clv_nlpid,
300 dissect_lsp_nlpid_clv
303 ISIS_CLV_L2_LSP_HOSTNAME,
305 &ett_isis_lsp_clv_hostname,
306 dissect_lsp_hostname_clv
309 ISIS_CLV_L2_LSP_TE_ROUTER_ID,
310 "Traffic Engineering Router ID",
311 &ett_isis_lsp_clv_te_router_id,
312 dissect_lsp_te_router_id_clv
315 ISIS_CLV_L2_LSP_EXT_IP_REACHABLE,
316 "Extended IP Reachability",
317 &ett_isis_lsp_clv_ext_ip_reachability,
318 dissect_lsp_ext_ip_reachability_clv
321 ISIS_CLV_L2_LSP_IPv6_REACHABLE,
323 &ett_isis_lsp_clv_ipv6_reachability,
324 dissect_lsp_ipv6_reachability_clv
327 ISIS_CLV_L2_LSP_IP_INTERFACE_ADDR,
328 "IP Interface address(es)",
329 &ett_isis_lsp_clv_ipv4_int_addr,
330 dissect_lsp_ip_int_addr_clv
333 ISIS_CLV_L2_LSP_IPv6_INTERFACE_ADDR,
334 "IPv6 Interface address(es)",
335 &ett_isis_lsp_clv_ipv6_int_addr,
336 dissect_lsp_ipv6_int_addr_clv
339 ISIS_CLV_L2_LSP_AUTHENTICATION_NS,
340 "Authentication(non spec)",
341 &ett_isis_lsp_clv_auth,
342 dissect_lsp_l2_auth_clv
345 ISIS_CLV_L2_LSP_AUTHENTICATION,
347 &ett_isis_lsp_clv_auth,
348 dissect_lsp_l2_auth_clv
353 &ett_isis_lsp_clv_mt,
357 ISIS_CLV_L2_LSP_MT_IS_REACHABLE,
358 "Multi Topology IS Reachability",
359 &ett_isis_lsp_clv_mt_is,
360 dissect_lsp_mt_is_reachability_clv
372 * Name: dissect_metric()
375 * Display a metric prefix portion. ISIS has the concept of multple
376 * metric per prefix (default, delay, expense, and error). This
377 * routine assists other dissectors by adding a single one of
378 * these to the display tree..
380 * The 8th(msbit) bit in the metric octet is the "supported" bit. The
381 * "default" support is required, so we support a "force_supported"
382 * flag that tells us that it MUST be zero (zero==supported,
383 * so it really should be a "not supported" in the boolean sense)
384 * and to display a protocol failure accordingly. Notably,
385 * Cisco IOS 12(6) blows this!
386 * The 7th bit must be zero (reserved).
389 * u_char * : packet data
390 * int : offset into packet data where we are.
391 * guint : length of clv we are decoding
392 * frame_data * : frame data (complete frame)
393 * proto_tree * : protocol display tree to fill out. May be NULL
394 * int : force supported. True is the supported bit MUST be zero.
397 * void, but we will add to proto tree if !NULL.
400 dissect_metric(proto_tree *tree, int offset, guint8 value,
401 char *pstr, int force_supported ) {
406 s = ISIS_LSP_CLV_METRIC_SUPPORTED(value);
407 proto_tree_add_text ( tree, NullTVB, offset, 1,
408 "%s Metric: %s%s %s%d:%d", pstr,
409 s ? "Not supported" : "Supported",
410 (s && force_supported) ? "(but is required to be)":"",
411 ISIS_LSP_CLV_METRIC_RESERVED(value) ? "(reserved bit != 0)":"",
412 ISIS_LSP_CLV_METRIC_VALUE(value), value );
417 * Name: dissect_lsp_ip_reachabillity_clv()
420 * Decode an IP reachability CLV. This can be either internal or
421 * external (the clv format does not change and which type we are
422 * displaying is put there by the dispatcher). All of these
423 * are a metric block followed by an IP addr and mask.
426 * u_char * : packet data
427 * int : current offset into packet data
428 * guint : length of this clv
429 * int : length of IDs in packet.
430 * frame_data * : frame data
431 * proto_tree * : proto tree to build on (may be null)
434 * void, will modify proto_tree if not null.
437 dissect_lsp_ip_reachability_clv(const u_char *pd, int offset,
438 guint length, int id_length, frame_data *fd, proto_tree *tree) {
440 proto_tree *ntree = NULL;
441 guint32 src, mask, prefix_len;
443 guint32 bitmasks[33] = {
445 0x00000008, 0x0000000c, 0x0000000e, 0x0000000f,
446 0x000000f8, 0x000000fc, 0x000000fe, 0x000000ff,
447 0x000008ff, 0x00000cff, 0x00000eff, 0x00000fff,
448 0x0000f8ff, 0x0000fcff, 0x0000feff, 0x0000ffff,
449 0x0008ffff, 0x000cffff, 0x000effff, 0x000fffff,
450 0x00f8ffff, 0x00fcffff, 0x00feffff, 0x00ffffff,
451 0x08ffffff, 0x0cffffff, 0x0effffff, 0x0fffffff,
452 0xf8ffffff, 0xfcffffff, 0xfeffffff, 0xffffffff
456 while ( length > 0 ) {
458 isis_dissect_unknown(offset, length, tree, fd,
459 "short IP reachability (%d vs 12)", length );
463 * Gotta build a sub-tree for all our pieces
466 memcpy(&src, &pd[offset+4], 4);
467 memcpy(&mask, &pd[offset+8], 4);
469 /* find out if the mask matches one of 33 possible prefix lengths */
473 while(prefix_len<=33) {
474 if (bitmasks[prefix_len++]==mask) {
480 /* 34 indicates no match -> must be a discontiguous netmask
481 lets dump the mask, otherwise print the prefix_len */
484 ti = proto_tree_add_text ( tree, NullTVB, offset, 12,
485 "IPv4 prefix: %s mask %s",
486 ip_to_str((guint8*)&src),
487 ip_to_str((guint8*)&mask));
489 ti = proto_tree_add_text ( tree, NullTVB, offset, 12,
490 "IPv4 prefix: %s/%d",
491 ip_to_str((guint8*)&src),
495 ntree = proto_item_add_subtree(ti,
496 ett_isis_lsp_clv_ip_reachability);
498 proto_tree_add_text (ntree, NullTVB, offset, 1,
499 "Default Metric: %d, %s, Distribution: %s",
500 ISIS_LSP_CLV_METRIC_VALUE(pd[offset]),
501 ISIS_LSP_CLV_METRIC_IE(pd[offset]) ? "External" : "Internal",
502 ISIS_LSP_CLV_METRIC_UPDOWN(pd[offset]) ? "down" : "up");
505 if (ISIS_LSP_CLV_METRIC_SUPPORTED(pd[offset+1])) {
506 proto_tree_add_text (ntree, NullTVB, offset+1, 1, "Delay Metric: Not supported");
508 proto_tree_add_text (ntree, NullTVB, offset+1, 1, "Delay Metric: %d, %s",
509 ISIS_LSP_CLV_METRIC_VALUE(pd[offset+1]),
510 ISIS_LSP_CLV_METRIC_IE(pd[offset+1]) ? "External" : "Internal");
513 if (ISIS_LSP_CLV_METRIC_SUPPORTED(pd[offset+2])) {
514 proto_tree_add_text (ntree, NullTVB, offset+2, 1, "Expense Metric: Not supported");
516 proto_tree_add_text (ntree, NullTVB, offset+2, 1, "Exense Metric: %d, %s",
517 ISIS_LSP_CLV_METRIC_VALUE(pd[offset+2]),
518 ISIS_LSP_CLV_METRIC_IE(pd[offset+2]) ? "External" : "Internal");
521 if (ISIS_LSP_CLV_METRIC_SUPPORTED(pd[offset+3])) {
522 proto_tree_add_text (ntree, NullTVB, offset+3, 1, "Error Metric: Not supported");
524 proto_tree_add_text (ntree, NullTVB, offset+3, 1, "Error Metric: %d, %s",
525 ISIS_LSP_CLV_METRIC_VALUE(pd[offset+3]),
526 ISIS_LSP_CLV_METRIC_IE(pd[offset+3]) ? "External" : "Internal");
535 * Name: dissect_lsp_ext_ip_reachability_clv()
537 * Description: Decode an Extended IP Reachability CLV - code 135.
539 * The extended IP reachability TLV is an extended version
540 * of the IP reachability TLVs (codes 128 and 130). It encodes
541 * the metric as a 32-bit unsigned interger and allows to add
545 * u_char * : packet data
546 * int : current offset into packet data
547 * guint : length of this clv
548 * int : length of IDs in packet.
549 * frame_data * : frame data
550 * proto_tree * : proto tree to build on (may be null)
553 * void, will modify proto_tree if not null.
556 dissect_lsp_ext_ip_reachability_clv(const u_char *pd, int offset,
557 guint length, int id_length, frame_data *fd, proto_tree *tree) {
558 proto_item *pi = NULL;
559 proto_tree *subtree = NULL;
561 guint8 bit_length, byte_length;
568 memset (prefix, 0, 4);
569 ctrl_info = pd[offset+4];
570 bit_length = ctrl_info & 0x3f;
571 byte_length = (bit_length + 7) / 8;
572 memcpy (prefix, &pd[offset+5], byte_length);
573 pi = proto_tree_add_text (tree, NullTVB, offset, 0,
574 "IPv4 prefix: %s/%d",
577 subtree = proto_item_add_subtree (pi,
578 ett_isis_lsp_part_of_clv_ext_ip_reachability);
580 proto_tree_add_text (subtree, NullTVB, offset, 4,
581 "Metric: %d, Distribution: %s", pntohl (&pd[offset]), ((ctrl_info & 0x80) == 0) ? "up" : "down" );
583 proto_tree_add_text (subtree, NullTVB, offset+4, 1,
584 "%s sub-TLVs present",
585 ((ctrl_info & 0x40) == 0) ? "no" : "" );
587 len = 5 + byte_length;
588 if ((ctrl_info & 0x40) != 0)
589 len += 1 + pd[offset+len] ;
590 proto_item_set_len (pi, len);
597 * Name: dissect_lsp_ipv6_reachability_clv()
599 * Description: Decode an IPv6 reachability CLV - code 236.
602 * u_char * : packet data
603 * int : current offset into packet data
604 * guint : length of this clv
605 * int : length of IDs in packet.
606 * frame_data * : frame data
607 * proto_tree * : proto tree to build on (may be null)
610 * void, will modify proto_tree if not null.
613 dissect_lsp_ipv6_reachability_clv(const u_char *pd, int offset,
614 guint length, int id_length, frame_data *fd, proto_tree *tree) {
616 proto_tree *ntree = NULL;
617 guint8 bit_length, byte_length;
618 struct e_in6_addr prefix;
625 memset (prefix.s6_addr, 0, 16);
628 bit_length = pd[offset+5];
629 byte_length = (bit_length + 7) / 8;
630 memcpy (prefix.s6_addr, &pd[offset+6], byte_length);
631 ti = proto_tree_add_text (tree, NullTVB, offset, 0,
633 ip6_to_str (&prefix),
635 ntree = proto_item_add_subtree (ti, ett_isis_lsp_part_of_clv_ipv6_reachability);
637 metric = pntohl (&pd[offset]);
638 proto_tree_add_text (ntree, NullTVB, offset, 4,
639 "Metric: %d", metric);
641 ctrl_info = pd[offset+4];
642 proto_tree_add_text (ntree, NullTVB, offset+4, 1,
643 "Distribution: %s, %s",
644 ((ctrl_info & 0x80) == 0) ? "up" : "down",
645 ((ctrl_info & 0x40) == 0) ? "internal" : "external" );
647 proto_tree_add_text (ntree, NullTVB, offset+4, 1,
648 "Reserved bits: 0x%x",
649 (ctrl_info & 0x1f) );
650 proto_tree_add_text (ntree, NullTVB, offset+4, 1,
652 ((ctrl_info & 0x20) == 0) ? "no" : "yes" );
654 len = 6 + byte_length;
655 if ((ctrl_info & 0x20) != 0)
656 len += 1 + pd[offset+len] ;
657 proto_item_set_len (ti, len);
664 * Name: dissect_lsp_nlpid_clv()
667 * Decode for a lsp packets NLPID clv. Calls into the
671 * u_char * : packet data
672 * int : current offset into packet data
673 * guint : length of this clv
674 * int : length of IDs in packet.
675 * frame_data * : frame data
676 * proto_tree * : proto tree to build on (may be null)
679 * void, will modify proto_tree if not null.
682 dissect_lsp_nlpid_clv(const u_char *pd, int offset,
683 guint length, int id_length, frame_data *fd, proto_tree *tree) {
684 isis_dissect_nlpid_clv(pd, offset, length, fd, tree );
688 * Name: dissect_lsp_mt_clv()
691 * Decode for a lsp packets Multi Topology clv. Calls into the
695 * u_char * : packet data
696 * int : current offset into packet data
697 * guint : length of this clv
698 * int : length of IDs in packet.
699 * frame_data * : frame data
700 * proto_tree * : proto tree to build on (may be null)
703 * void, will modify proto_tree if not null.
707 dissect_lsp_mt_clv(const u_char *pd, int offset,
708 guint length, int id_length, frame_data *fd, proto_tree *tree) {
709 isis_dissect_mt_clv(pd, offset, length, fd, tree,
710 hf_isis_lsp_clv_mt );
714 * Name: dissect_lsp_hostname_clv()
717 * Decode for a lsp packets hostname clv. Calls into the
721 * u_char * : packet data
722 * int : current offset into packet data
723 * guint : length of this clv
724 * int : length of IDs in packet.
725 * frame_data * : frame data
726 * proto_tree * : proto tree to build on (may be null)
729 * void, will modify proto_tree if not null.
733 dissect_lsp_hostname_clv(const u_char *pd, int offset,
734 guint length, int id_length, frame_data *fd, proto_tree *tree) {
735 isis_dissect_hostname_clv(pd, offset, length, fd, tree );
740 * Name: dissect_lsp_te_router_id_clv()
743 * Decode for a lsp packets Traffic Engineering ID clv. Calls into the
747 * u_char * : packet data
748 * int : current offset into packet data
749 * guint : length of this clv
750 * int : length of IDs in packet.
751 * frame_data * : frame data
752 * proto_tree * : proto tree to build on (may be null)
755 * void, will modify proto_tree if not null.
758 dissect_lsp_te_router_id_clv(const u_char *pd, int offset,
759 guint length, int id_length, frame_data *fd, proto_tree *tree) {
760 isis_dissect_te_router_id_clv(pd, offset, length, fd, tree,
761 hf_isis_lsp_clv_te_router_id );
768 * Name: dissect_lsp_ip_int_addr_clv()
771 * Decode for a lsp packets ip interface addr clv. Calls into the
775 * u_char * : packet data
776 * int : current offset into packet data
777 * guint : length of this clv
778 * int : length of IDs in packet.
779 * frame_data * : frame data
780 * proto_tree * : proto tree to build on (may be null)
783 * void, will modify proto_tree if not null.
786 dissect_lsp_ip_int_addr_clv(const u_char *pd, int offset,
787 guint length, int id_length, frame_data *fd, proto_tree *tree) {
788 isis_dissect_ip_int_clv(pd, offset, length, fd, tree,
789 hf_isis_lsp_clv_ipv4_int_addr );
793 * Name: dissect_lsp_ipv6_int_addr_clv()
795 * Description: Decode an IPv6 interface addr CLV - code 232.
797 * Calls into the clv common one.
800 * u_char * : packet data
801 * int : current offset into packet data
802 * guint : length of this clv
803 * int : length of IDs in packet.
804 * frame_data * : frame data
805 * proto_tree * : proto tree to build on (may be null)
808 * void, will modify proto_tree if not null.
811 dissect_lsp_ipv6_int_addr_clv(const u_char *pd, int offset,
812 guint length, int id_length, frame_data *fd, proto_tree *tree) {
813 isis_dissect_ipv6_int_clv(pd, offset, length, fd, tree,
814 hf_isis_lsp_clv_ipv6_int_addr );
818 * Name: dissect_lsp_L1_auth_clv()
821 * Decode for a lsp packets authenticaion clv. Calls into the
822 * clv common one. An auth inside a L1 LSP is a per area password
825 * u_char * : packet data
826 * int : current offset into packet data
827 * guint : length of this clv
828 * int : length of IDs in packet.
829 * frame_data * : frame data
830 * proto_tree * : proto tree to build on (may be null)
833 * void, will modify proto_tree if not null.
836 dissect_lsp_l1_auth_clv(const u_char *pd, int offset,
837 guint length, int id_length, frame_data *fd, proto_tree *tree) {
838 isis_dissect_authentication_clv(pd, offset, length, fd, tree,
839 "Per area authentication" );
843 * Name: dissect_lsp_L2_auth_clv()
846 * Decode for a lsp packets authenticaion clv. Calls into the
847 * clv common one. An auth inside a L2 LSP is a per domain password
850 * u_char * : packet data
851 * int : current offset into packet data
852 * guint : length of this clv
853 * int : length of IDs in packet.
854 * frame_data * : frame data
855 * proto_tree * : proto tree to build on (may be null)
858 * void, will modify proto_tree if not null.
861 dissect_lsp_l2_auth_clv(const u_char *pd, int offset,
862 guint length, int id_length, frame_data *fd, proto_tree *tree) {
863 isis_dissect_authentication_clv(pd, offset, length, fd, tree,
864 "Per domain authentication" );
868 * Name: dissect_lsp_area_address_clv()
871 * Decode for a lsp packet's area address clv. Call into clv common
875 * u_char * : packet data
876 * int : offset into packet data where we are.
877 * guint : length of clv we are decoding
878 * int : length of IDs in packet.
879 * frame_data * : frame data (complete frame)
880 * proto_tree * : protocol display tree to fill out. May be NULL
883 * void, but we will add to proto tree if !NULL.
886 dissect_lsp_area_address_clv(const u_char *pd, int offset,
887 guint length, int id_length, frame_data *fd, proto_tree *tree) {
888 isis_dissect_area_address_clv(pd, offset, length, fd, tree );
892 * Name: dissect_lsp_eis_neighbors_clv_inner()
895 * Real work horse for showing neighbors. This means we decode the
896 * first octet as either virtual/!virtual (if show_virtual param is
897 * set), or as a must == 0 reserved value.
899 * Once past that, we decode n neighbor elements. Each neighbor
900 * is comprised of a metric block (is dissect_metric) and the
904 * u_char * : packet data
905 * int : offset into packet data where we are.
906 * guint : length of clv we are decoding
907 * int : length of IDs in packet.
908 * frame_data * : frame data (complete frame)
909 * proto_tree * : protocol display tree to fill out. May be NULL
910 * int : set to decode first octet as virtual vs reserved == 0
911 * int : set to indicate EIS instead of IS (6 octet per addr instead of 7)
914 * void, but we will add to proto tree if !NULL.
917 dissect_lsp_eis_neighbors_clv_inner(const u_char *pd, int offset,
918 guint length, int id_length, frame_data *fd, proto_tree *tree,
919 int show_virtual, int is_eis) {
921 proto_tree *ntree = NULL;
925 id_length++; /* IDs are one octet longer in IS neighbours */
927 if ( show_virtual ) {
928 /* virtual path flag */
929 proto_tree_add_text ( tree, NullTVB, offset, 1,
930 &pd[offset] ? "IsNotVirtual" : "IsVirtual" );
932 proto_tree_add_text ( tree, NullTVB, offset, 1,
933 "Reserved value 0x%02x, must == 0",
940 tlen = 4 + id_length;
942 while ( length > 0 ) {
944 isis_dissect_unknown(offset, length, tree, fd,
945 "short E/IS reachability (%d vs %d)", length,
950 * Gotta build a sub-tree for all our pieces
954 ti = proto_tree_add_text ( tree, NullTVB, offset, tlen,
956 print_system_id( pd + offset + 4, id_length ) );
958 ti = proto_tree_add_text ( tree, NullTVB, offset, tlen,
960 print_system_id( pd + offset + 4, id_length ) );
962 ntree = proto_item_add_subtree(ti,
963 ett_isis_lsp_clv_is_neighbors);
967 proto_tree_add_text (ntree, NullTVB, offset, 1,
968 "Default Metric: %d, %s",
969 ISIS_LSP_CLV_METRIC_VALUE(pd[offset]),
970 ISIS_LSP_CLV_METRIC_IE(pd[offset]) ? "External" : "Internal");
972 if (ISIS_LSP_CLV_METRIC_SUPPORTED(pd[offset+1])) {
973 proto_tree_add_text (ntree, NullTVB, offset+1, 1, "Delay Metric: Not supported");
975 proto_tree_add_text (ntree, NullTVB, offset+1, 1, "Delay Metric: %d, %s",
976 ISIS_LSP_CLV_METRIC_VALUE(pd[offset+1]),
977 ISIS_LSP_CLV_METRIC_IE(pd[offset+1]) ? "External" : "Internal");
981 if (ISIS_LSP_CLV_METRIC_SUPPORTED(pd[offset+2])) {
982 proto_tree_add_text (ntree, NullTVB, offset+2, 1, "Expense Metric: Not supported");
984 proto_tree_add_text (ntree, NullTVB, offset+2, 1, "Expense Metric: %d, %s",
985 ISIS_LSP_CLV_METRIC_VALUE(pd[offset+2]),
986 ISIS_LSP_CLV_METRIC_IE(pd[offset+2]) ? "External" : "Internal");
989 if (ISIS_LSP_CLV_METRIC_SUPPORTED(pd[offset+3])) {
990 proto_tree_add_text (ntree, NullTVB, offset+3, 1, "Error Metric: Not supported");
992 proto_tree_add_text (ntree, NullTVB, offset+3, 1, "Error Metric: %d, %s",
993 ISIS_LSP_CLV_METRIC_VALUE(pd[offset+3]),
994 ISIS_LSP_CLV_METRIC_IE(pd[offset+3]) ? "External" : "Internal");
1004 * Name: dissect_lsp_l1_is_neighbors_clv()
1007 * Dispatch a l1 intermediate system neighbor by calling
1008 * the inner function with show virtual set to TRUE and is es set to FALSE.
1011 * u_char * : packet data
1012 * int : offset into packet data where we are.
1013 * guint : length of clv we are decoding
1014 * int : length of IDs in packet.
1015 * frame_data * : frame data (complete frame)
1016 * proto_tree * : protocol display tree to fill out. May be NULL
1019 * void, but we will add to proto tree if !NULL.
1022 dissect_lsp_l1_is_neighbors_clv(const u_char *pd, int offset,
1023 guint length, int id_length, frame_data *fd, proto_tree *tree) {
1024 dissect_lsp_eis_neighbors_clv_inner( pd, offset, length, id_length,
1025 fd, tree, TRUE, FALSE );
1029 * Name: dissect_lsp_l1_es_neighbors_clv()
1032 * Dispatch a l1 end or intermediate system neighbor by calling
1033 * the inner function with show virtual set to TRUE and es set to TRUE.
1036 * u_char * : packet data
1037 * int : offset into packet data where we are.
1038 * guint : length of clv we are decoding
1039 * int : length of IDs in packet.
1040 * frame_data * : frame data (complete frame)
1041 * proto_tree * : protocol display tree to fill out. May be NULL
1044 * void, but we will add to proto tree if !NULL.
1047 dissect_lsp_l1_es_neighbors_clv(const u_char *pd, int offset,
1048 guint length, int id_length, frame_data *fd, proto_tree *tree) {
1049 dissect_lsp_eis_neighbors_clv_inner( pd, offset, length, id_length,
1050 fd, tree, TRUE, TRUE);
1054 * Name: dissect_lsp_l2_is_neighbors_clv()
1057 * Dispatch a l2 intermediate system neighbor by calling
1058 * the inner function with show virtual set to FALSE, and is es set
1062 * u_char * : packet data
1063 * int : offset into packet data where we are.
1064 * guint : length of clv we are decoding
1065 * int : length of IDs in packet.
1066 * frame_data * : frame data (complete frame)
1067 * proto_tree * : protocol display tree to fill out. May be NULL
1070 * void, but we will add to proto tree if !NULL.
1073 dissect_lsp_l2_is_neighbors_clv(const u_char *pd, int offset,
1074 guint length, int id_length, frame_data *fd, proto_tree *tree) {
1075 dissect_lsp_eis_neighbors_clv_inner(pd, offset, length, id_length,
1076 fd, tree, FALSE, FALSE);
1080 * Name: dissect_subclv_admin_group ()
1082 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1084 * This function is called by dissect_lsp_ext_is_reachability_clv()
1085 * for dissect the administrive group sub-CLV (code 3).
1088 * u_char * : packet data
1089 * int : offset into packet data where we are (beginning of the sub_clv value).
1090 * proto_tree * : protocol display tree to fill out.
1096 dissect_subclv_admin_group (const u_char *pd, int offset, proto_tree *tree) {
1103 ti = proto_tree_add_text (tree, NullTVB, offset-2, 6, "Administrative group(s):");
1104 ntree = proto_item_add_subtree (ti, ett_isis_lsp_subclv_admin_group);
1106 clv_value = pntohl (&pd[offset]);
1108 for (i = 0 ; i < 32 ; i++) {
1109 if ( (clv_value & mask) != 0 ) {
1110 proto_tree_add_text (ntree, NullTVB, offset, 4, "group %d", i);
1117 * Name: dissect_subclv_max_bw ()
1119 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1121 * This function is called by dissect_lsp_ext_is_reachability_clv()
1122 * for dissect the maximum link bandwidth sub-CLV (code 9).
1125 * u_char * : packet data
1126 * int : offset into packet data where we are (beginning of the sub_clv value).
1127 * proto_tree * : protocol display tree to fill out.
1133 dissect_subclv_max_bw (const u_char *pd, int offset, proto_tree *tree) {
1137 ui = pntohl (&pd[offset]);
1138 memcpy (&bw, &ui, 4);
1139 proto_tree_add_text (tree, NullTVB, offset-2, 6,
1140 "Maximum link bandwidth : %.2f Mbps", bw*8/1000000 );
1144 * Name: dissect_subclv_rsv_bw ()
1146 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1148 * This function is called by dissect_lsp_ext_is_reachability_clv()
1149 * for dissect the reservable link bandwidth sub-CLV (code 10).
1152 * u_char * : packet data
1153 * int : offset into packet data where we are (beginning of the sub_clv value).
1154 * proto_tree * : protocol display tree to fill out.
1160 dissect_subclv_rsv_bw (const u_char *pd, int offset, proto_tree *tree) {
1164 ui = pntohl (&pd[offset]);
1165 memcpy (&bw, &ui, 4);
1166 proto_tree_add_text (tree, NullTVB, offset-2, 6,
1167 "Reservable link bandwidth: %.2f Mbps", bw*8/1000000 );
1171 * Name: dissect_subclv_unrsv_bw ()
1173 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
1175 * This function is called by dissect_lsp_ext_is_reachability_clv()
1176 * for dissect the unreserved bandwidth sub-CLV (code 11).
1179 * u_char * : packet data
1180 * int : offset into packet data where we are (beginning of the sub_clv value).
1181 * proto_tree * : protocol display tree to fill out.
1187 dissect_subclv_unrsv_bw (const u_char *pd, int offset, proto_tree *tree) {
1194 ti = proto_tree_add_text (tree, NullTVB, offset-2, 34, "Unreserved bandwidth:");
1195 ntree = proto_item_add_subtree (ti, ett_isis_lsp_subclv_unrsv_bw);
1197 for (i = 0 ; i < 8 ; i++) {
1198 ui = pntohl (&pd[offset]);
1199 memcpy (&bw, &ui, 4);
1200 proto_tree_add_text (ntree, NullTVB, offset+4*i, 4,
1201 "priority level %d: %.2f Mbps", i, bw*8/1000000 );
1206 * Name: dissect_lsp_ext_is_reachability_clv()
1208 * Description: Decode a Extended IS Reachability CLV - code 22
1210 * The extended IS reachability TLV is an extended version
1211 * of the IS reachability TLV (code 2). It encodes the metric
1212 * as a 24-bit unsigned interger and allows to add sub-CLV(s).
1215 * u_char * : packet data
1216 * int : offset into packet data where we are.
1217 * guint : length of clv we are decoding
1218 * int : length of IDs in packet.
1219 * frame_data * : frame data (complete frame)
1220 * proto_tree * : protocol display tree to fill out. May be NULL
1223 * void, but we will add to proto tree if !NULL.
1226 dissect_lsp_ext_is_reachability_clv(const u_char *pd, int offset,
1227 guint length, int id_length, frame_data *fd, proto_tree *tree) {
1229 proto_tree *ntree = NULL;
1232 guint8 clv_code, clv_len;
1236 while (length > 0) {
1237 ti = proto_tree_add_text (tree, NullTVB, offset, 0,
1239 print_system_id (&pd[offset], 7) );
1240 ntree = proto_item_add_subtree (ti,
1241 ett_isis_lsp_part_of_clv_ext_is_reachability );
1243 proto_tree_add_text (ntree, NullTVB, offset+7, 3,
1244 "Metric: %d", pntoh24 (&pd[offset+7]) );
1246 subclvs_len = pd[offset+10];
1247 if (subclvs_len == 0) {
1248 proto_tree_add_text (ntree, NullTVB, offset+10, 1, "no sub-TLVs present");
1252 while (i < subclvs_len) {
1253 clv_code = pd[offset+11+i];
1254 clv_len = pd[offset+12+i];
1257 dissect_subclv_admin_group (pd, offset+13+i, ntree);
1260 proto_tree_add_text (ntree, NullTVB, offset+11+i, 6,
1261 "IPv4 interface address: %s", ip_to_str (&pd[offset+13+i]) );
1264 proto_tree_add_text (ntree, NullTVB, offset+11+i, 6,
1265 "IPv4 neighbor address: %s", ip_to_str (&pd[offset+13+i]) );
1268 dissect_subclv_max_bw (pd, offset+13+i, ntree);
1271 dissect_subclv_rsv_bw (pd, offset+13+i, ntree);
1274 dissect_subclv_unrsv_bw (pd, offset+13+i, ntree);
1277 proto_tree_add_text (ntree, NullTVB, offset+11+i, 5,
1278 "Traffic engineering default metric: %d",
1279 pntoh24 (&pd[offset+13+i]) );
1286 proto_tree_add_text (ntree, NullTVB, offset+11+i, clv_len+2,
1287 "Unknown Cisco specific extensions: code %d, length %d",
1288 clv_code, clv_len );
1291 proto_tree_add_text (ntree, NullTVB, offset+11+i, clv_len+2,
1292 "Unknown sub-CLV: code %d, length %d", clv_code, clv_len );
1299 len = 11 + subclvs_len;
1300 proto_item_set_len (ti, len);
1309 dissect_lsp_mt_is_reachability_clv(const u_char *pd, int offset,
1310 guint length, int id_length, frame_data *fd, proto_tree *tree) {
1312 proto_tree *ntree = NULL;
1321 while (length > 0) {
1323 /* fetch two bytes */
1325 mt_block=(*(pd+offset)<<8)+(*(pd+offset+1));
1328 /* mask out the lower 12 bits */
1329 switch(mt_block&0x0fff) {
1331 strcpy(mt_desc,"IPv4 unicast");
1334 strcpy(mt_desc,"In-Band Management");
1337 strcpy(mt_desc,"IPv6 unicast");
1340 strcpy(mt_desc,"Multicast");
1343 strcpy(mt_desc,"Development, Experimental or Proprietary");
1346 strcpy(mt_desc,"Reserved for IETF Consensus");
1349 proto_tree_add_text ( tree, NullTVB, offset, 2 ,
1350 "%s Topology (0x%x)",
1354 ti = proto_tree_add_text (tree, NullTVB, offset+2, 0,
1356 print_system_id (&pd[offset+2], 7) );
1358 ntree = proto_item_add_subtree (ti,
1359 ett_isis_lsp_part_of_clv_mt_is );
1361 proto_tree_add_text (ntree, NullTVB, offset+9, 3,
1362 "Metric: %d", pntoh24 (&pd[offset+9]) );
1364 subclvs_len = pd[offset+12];
1365 if (subclvs_len == 0) {
1366 proto_tree_add_text (ntree, NullTVB, offset+12, 1, "no sub-TLVs present");
1368 proto_tree_add_text (ntree, NullTVB, offset+12, 1, "sub-TLVs present");
1371 len = 13 + subclvs_len;
1372 proto_item_set_len (ti, len);
1380 * Name: dissect_lsp_partition_dis_clv()
1383 * This CLV is used to indicate which system is the designated
1384 * IS for partition repair. This means just putting out the
1385 * "id_length"-octet IS.
1388 * u_char * : packet data
1389 * int : offset into packet data where we are.
1390 * guint : length of clv we are decoding
1391 * int : length of IDs in packet.
1392 * frame_data * : frame data (complete frame)
1393 * proto_tree * : protocol display tree to fill out. May be NULL
1396 * void, but we will add to proto tree if !NULL.
1399 dissect_lsp_partition_dis_clv(const u_char *pd, int offset,
1400 guint length, int id_length, frame_data *fd, proto_tree *tree) {
1402 if ( length < id_length ) {
1403 isis_dissect_unknown(offset, length, tree, fd,
1404 "short lsp parition DIS(%d vs %d)", length,
1409 * Gotta build a sub-tree for all our pieces
1412 proto_tree_add_text ( tree, NullTVB, offset, id_length,
1413 "Partition designated L2 IS: %s",
1414 print_system_id( pd + offset, id_length ) );
1416 length -= id_length;
1417 offset += id_length;
1419 isis_dissect_unknown(offset, length, tree, fd,
1420 "Long lsp parition DIS, %d left over", length );
1426 * Name: dissect_lsp_prefix_neighbors_clv()
1429 * The prefix CLV describes what other (OSI) networks we can reach
1430 * and what their cost is. It is built from a metric block
1431 * (see dissect_metric) followed by n addresses.
1434 * u_char * : packet data
1435 * int : offset into packet data where we are.
1436 * guint : length of clv we are decoding
1437 * int : length of IDs in packet.
1438 * frame_data * : frame data (complete frame)
1439 * proto_tree * : protocol display tree to fill out. May be NULL
1442 * void, but we will add to proto tree if !NULL.
1445 dissect_lsp_prefix_neighbors_clv(const u_char *pd, int offset,
1446 guint length, int id_length, frame_data *fd, proto_tree *tree) {
1451 isis_dissect_unknown(offset, length, tree, fd,
1452 "Short lsp prefix neighbors (%d vs 4)", length );
1456 dissect_metric ( tree, offset, pd[offset], "Default", TRUE );
1457 dissect_metric ( tree, offset + 1, pd[offset+1],
1459 dissect_metric ( tree, offset + 2, pd[offset+2],
1461 dissect_metric ( tree, offset + 3, pd[offset+3],
1466 while ( length > 0 ) {
1470 isis_dissect_unknown(offset, length, tree, fd,
1471 "Zero payload space after length in prefix neighbor" );
1474 if ( mylen > length) {
1475 isis_dissect_unknown(offset, length, tree, fd,
1476 "Interal length of prefix neighbor too long (%d vs %d)",
1482 * Lets turn the area address into "standard" 0000.0000.etc
1485 sbuf = print_area( pd + offset + 1, mylen );
1486 /* and spit it out */
1488 proto_tree_add_text ( tree, NullTVB, offset, mylen + 1,
1489 "Area address (%d): %s", mylen, sbuf );
1491 offset += mylen + 1;
1492 length -= mylen; /* length already adjusted for len fld*/
1497 * Name: isis_lsp_decode_lsp_id()
1500 * Display a LSP id into the display tree.
1503 * char * : title string
1504 * proto_tree * : tree to display into. REQUIRED
1505 * u_char * : packet data
1506 * int : offset into packet data where we are.
1507 * int : length of IDs in packet.
1510 * void, but we will add to proto tree
1513 isis_lsp_decode_lsp_id(char *tstr, proto_tree *tree, const u_char *pd,
1514 int offset, int id_length ) {
1515 proto_tree_add_text(tree, NullTVB, offset, id_length + 2,
1516 "%s: %s.%02x-%02x", tstr,
1517 print_system_id( pd + offset, id_length ),
1518 pd[offset + id_length],
1519 pd[offset + id_length + 1] );
1523 * Name: isis_dissect_isis_lsp()
1526 * Print out the LSP part of the main header and then call the CLV
1527 * de-mangler with the right list of valid CLVs.
1530 * int : LSP type, a la packet-isis.h ISIS_TYPE_* values
1531 * int : header length of packet.
1532 * int : length of IDs in packet.
1533 * u_char * : packet data
1534 * int offset : our offset into packet data.
1535 * frame_data * : frame data
1536 * proto_tree * : protocol display tree to add to. May be NULL.
1539 * void, but we will add to proto tree if !NULL.
1542 isis_dissect_isis_lsp(int lsp_type, int header_length, int id_length,
1543 const u_char *pd, int offset, frame_data *fd, proto_tree *tree){
1545 proto_tree *lsp_tree = NULL;
1549 int inx, q, some, value, len;
1551 OLD_CHECK_DISPLAY_AS_DATA(proto_isis_lsp, pd, offset, fd, tree);
1553 hlen = 2+2+id_length+2+4+2+1;
1555 if (!BYTES_ARE_IN_FRAME(offset, hlen)) {
1556 isis_dissect_unknown(offset, hlen, tree, fd,
1557 "not enough capture data for header (%d vs %d)",
1558 hlen, END_OF_FRAME);
1563 ti = proto_tree_add_item(tree, proto_isis_lsp, NullTVB,
1564 offset, END_OF_FRAME, FALSE);
1565 lsp_tree = proto_item_add_subtree(ti, ett_isis_lsp);
1568 pdu_length = pntohs(&pd[offset]);
1570 proto_tree_add_uint(lsp_tree, hf_isis_lsp_pdu_length, NullTVB,
1571 offset, 2, pdu_length);
1576 proto_tree_add_uint(lsp_tree, hf_isis_lsp_remaining_life, NullTVB,
1577 offset, 2, pntohs(&pd[offset]));
1582 isis_lsp_decode_lsp_id("LSP ID", lsp_tree, pd, offset,
1585 offset += id_length + 2;
1588 proto_tree_add_uint(lsp_tree, hf_isis_lsp_sequence_number, NullTVB,
1590 pntohl(&pd[offset]));
1595 /* XXX -> we could validate the cksum here! */
1596 proto_tree_add_uint(lsp_tree, hf_isis_lsp_checksum, NullTVB,
1597 offset, 2, pntohs(&pd[offset]));
1603 * We need to build our type block values.
1607 value = ISIS_LSP_ATT(pd[offset]);
1609 for ( q = (1<<ISIS_LSP_ATT_SHIFT); q > 0; q = q >> 1 ){
1614 strcat ( sbuf, isis_lsp_attached_bits[inx] );
1619 strcat ( sbuf, "default-only" );
1621 proto_tree_add_text(lsp_tree, NullTVB, offset + 18, 1,
1622 "Type block(0x%02x): P:%d, Supported metric(s): %s, OL:%d, istype:%s",
1624 ISIS_LSP_PARTITION(pd[offset]) ? 1 : 0,
1626 ISIS_LSP_HIPPITY(pd[offset]) ? 1 : 0,
1627 val_to_str(ISIS_LSP_IS_TYPE(pd[offset]),
1628 isis_lsp_istype_vals, "Unknown (0x%x)")
1633 len = pdu_length - header_length;
1635 isis_dissect_unknown(offset, header_length, tree, fd,
1636 "packet header length %d went beyond packet",
1641 * Now, we need to decode our CLVs. We need to pass in
1642 * our list of valid ones!
1644 if (lsp_type == ISIS_TYPE_L1_LSP){
1645 isis_dissect_clvs ( clv_l1_lsp_opts, len, id_length, pd,
1646 offset, fd, lsp_tree, ett_isis_lsp_clv_unknown );
1648 isis_dissect_clvs ( clv_l2_lsp_opts, len, id_length, pd,
1649 offset, fd, lsp_tree, ett_isis_lsp_clv_unknown );
1653 * Name: proto_register_isis_lsp()
1656 * Register our protocol sub-sets with protocol manager.
1657 * NOTE: this procedure is autolinked by the makefile process that
1661 * u_char * : packet data
1662 * int : offset into packet data where we are.
1663 * guint : length of clv we are decoding
1664 * frame_data * : frame data (complete frame)
1665 * proto_tree * : protocol display tree to fill out. May be NULL
1668 * void, but we will add to proto tree if !NULL.
1671 proto_register_isis_lsp(void) {
1672 static hf_register_info hf[] = {
1673 { &hf_isis_lsp_pdu_length,
1674 { "PDU length", "isis_lsp.pdu_length", FT_UINT16,
1675 BASE_DEC, NULL, 0x0, "", HFILL }},
1677 { &hf_isis_lsp_remaining_life,
1678 { "Remaining lifetime", "isis_lsp.remaining_life", FT_UINT16,
1679 BASE_DEC, NULL, 0x0, "", HFILL }},
1681 { &hf_isis_lsp_sequence_number,
1682 { "Sequence number", "isis_lsp.sequence_number",
1683 FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1685 { &hf_isis_lsp_checksum,
1686 { "Checksum", "isis_lsp.checksum",FT_UINT16,
1687 BASE_HEX, NULL, 0x0, "", HFILL }},
1689 { &hf_isis_lsp_clv_ipv4_int_addr,
1690 { "IPv4 interface address", "isis_lsp.clv_ipv4_int_addr", FT_IPv4,
1691 BASE_NONE, NULL, 0x0, "", HFILL }},
1693 { &hf_isis_lsp_clv_ipv6_int_addr,
1694 { "IPv6 interface address", "isis_lsp.clv_ipv6_int_addr", FT_IPv6,
1695 BASE_NONE, NULL, 0x0, "", HFILL }},
1697 { &hf_isis_lsp_clv_te_router_id,
1698 { "Traffic Engineering Router ID", "isis_lsp.clv_te_router_id", FT_IPv4,
1699 BASE_NONE, NULL, 0x0, "", HFILL }},
1701 static gint *ett[] = {
1703 &ett_isis_lsp_clv_area_addr,
1704 &ett_isis_lsp_clv_is_neighbors,
1705 &ett_isis_lsp_clv_ext_is_reachability, /* CLV 22 */
1706 &ett_isis_lsp_part_of_clv_ext_is_reachability,
1707 &ett_isis_lsp_subclv_admin_group,
1708 &ett_isis_lsp_subclv_unrsv_bw,
1709 &ett_isis_lsp_clv_unknown,
1710 &ett_isis_lsp_clv_partition_dis,
1711 &ett_isis_lsp_clv_prefix_neighbors,
1712 &ett_isis_lsp_clv_auth,
1713 &ett_isis_lsp_clv_nlpid,
1714 &ett_isis_lsp_clv_hostname,
1715 &ett_isis_lsp_clv_ipv4_int_addr,
1716 &ett_isis_lsp_clv_ipv6_int_addr, /* CLV 232 */
1717 &ett_isis_lsp_clv_te_router_id,
1718 &ett_isis_lsp_clv_ip_reachability,
1719 &ett_isis_lsp_clv_ext_ip_reachability, /* CLV 135 */
1720 &ett_isis_lsp_part_of_clv_ext_ip_reachability,
1721 &ett_isis_lsp_clv_ipv6_reachability, /* CLV 236 */
1722 &ett_isis_lsp_part_of_clv_ipv6_reachability,
1723 &ett_isis_lsp_clv_mt,
1724 &ett_isis_lsp_clv_mt_is,
1725 &ett_isis_lsp_part_of_clv_mt_is,
1728 proto_isis_lsp = proto_register_protocol(PROTO_STRING_LSP,
1729 "ISIS LSP", "isis_lsp");
1730 proto_register_field_array(proto_isis_lsp, hf, array_length(hf));
1731 proto_register_subtree_array(ett, array_length(ett));