HACK: 2nd try to match RowsetProperties
[wireshark-wip.git] / epan / dissectors / packet-isis-lsp.c
blob73220d910d0c92568435436d387260a099e4ea6f
1 /* packet-isis-lsp.c
2 * Routines for decoding isis lsp packets and their CLVs
4 * $Id$
5 * Stuart Stanley <stuarts@mxmail.net>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * Copyright 2011, Malgi Nikitha Vivekananda <malgi.nikitha@ipinfusion.com>
27 * Krishnamurthy Mayya <krishnamurthy.mayya@ipinfusion.com>
28 * - Decoding for Router Capability TLV and associated subTLVs as per RFC 6326
29 * - Decoding for Group Address TLV and associated subTLVs as per RFC 6326
32 #include "config.h"
34 #include <glib.h>
36 #include <epan/ipv4.h>
37 #include <epan/packet.h>
38 #include "packet-osi.h"
39 #include "packet-isis.h"
40 #include "packet-isis-clv.h"
41 #include "packet-isis-lsp.h"
42 #include <epan/addr_resolv.h>
43 #include <epan/addr_and_mask.h>
44 #include <epan/expert.h>
46 /* Sub-TLVs under Router Capability TLV
47 As per RFC 6326 section 2.3 */
48 #define TRILL_VERSION 12
49 #define NICKNAME 6
50 #define TREES 7
51 #define TREE_IDENTIFIER 8
52 #define TREES_USED_IDENTIFIER 9
53 #define INTERESTED_VLANS 10
54 #define VLAN_GROUP 13
57 /*Sub-TLVs under Group Address TLV*/
58 #define GRP_MAC_ADDRESS 1
59 #define FP_HMAC_SWID_MASK G_GINT64_CONSTANT(0xFFFF00000000)
60 #define FP_HMAC_SSWID_MASK G_GINT64_CONSTANT(0x0000FFFF0000)
61 #define FP_HMAC_LID_MASK G_GINT64_CONSTANT(0x00000000FFFF)
64 /* lsp packets */
65 static int hf_isis_lsp_pdu_length = -1;
66 static int hf_isis_lsp_remaining_life = -1;
67 static int hf_isis_lsp_sequence_number = -1;
68 static int hf_isis_lsp_lsp_id = -1;
69 static int hf_isis_lsp_hostname = -1;
70 static int hf_isis_lsp_checksum = -1;
71 static int hf_isis_lsp_checksum_bad = -1;
72 static int hf_isis_lsp_checksum_good = -1;
73 static int hf_isis_lsp_clv_ipv4_int_addr = -1;
74 static int hf_isis_lsp_clv_ipv6_int_addr = -1;
75 static int hf_isis_lsp_clv_te_router_id = -1;
76 static int hf_isis_lsp_clv_mt = -1;
77 static int hf_isis_lsp_p = -1;
78 static int hf_isis_lsp_att = -1;
79 static int hf_isis_lsp_hippity = -1;
80 static int hf_isis_lsp_is_type = -1;
81 static int hf_isis_lsp_root_id = -1;
82 static int hf_isis_lsp_spb_link_metric = -1;
83 static int hf_isis_lsp_spb_port_count = -1;
84 static int hf_isis_lsp_spb_port_id = -1;
85 static int hf_isis_lsp_spb_sr_bit = -1;
86 static int hf_isis_lsp_spb_spvid = -1;
88 static gint ett_isis_lsp = -1;
89 static gint ett_isis_lsp_info = -1;
90 static gint ett_isis_lsp_att = -1;
91 static gint ett_isis_lsp_cksum = -1;
92 static gint ett_isis_lsp_clv_area_addr = -1;
93 static gint ett_isis_lsp_clv_is_neighbors = -1;
94 static gint ett_isis_lsp_clv_ext_is_reachability = -1; /* CLV 22 */
95 static gint ett_isis_lsp_part_of_clv_ext_is_reachability = -1;
96 static gint ett_isis_lsp_subclv_admin_group = -1;
97 static gint ett_isis_lsp_subclv_unrsv_bw = -1;
98 static gint ett_isis_lsp_subclv_spb_link_metric = -1;
99 static gint ett_isis_lsp_clv_unknown = -1;
100 static gint ett_isis_lsp_clv_partition_dis = -1;
101 static gint ett_isis_lsp_clv_prefix_neighbors = -1;
102 static gint ett_isis_lsp_clv_nlpid = -1;
103 static gint ett_isis_lsp_clv_hostname = -1;
104 static gint ett_isis_lsp_clv_te_router_id = -1;
105 static gint ett_isis_lsp_clv_authentication = -1;
106 static gint ett_isis_lsp_clv_ip_authentication = -1;
107 static gint ett_isis_lsp_clv_ipv4_int_addr = -1;
108 static gint ett_isis_lsp_clv_ipv6_int_addr = -1; /* CLV 232 */
109 static gint ett_isis_lsp_clv_mt_cap = -1;
110 static gint ett_isis_lsp_clv_mt_cap_spb_instance = -1;
111 static gint ett_isis_lsp_clv_mt_cap_spbm_service_identifier = -1;
112 static gint ett_isis_lsp_clv_ip_reachability = -1;
113 static gint ett_isis_lsp_clv_ip_reach_subclv = -1;
114 static gint ett_isis_lsp_clv_ext_ip_reachability = -1; /* CLV 135 */
115 static gint ett_isis_lsp_part_of_clv_ext_ip_reachability = -1;
116 static gint ett_isis_lsp_clv_ipv6_reachability = -1; /* CLV 236 */
117 static gint ett_isis_lsp_part_of_clv_ipv6_reachability = -1;
118 static gint ett_isis_lsp_clv_mt = -1;
119 static gint ett_isis_lsp_clv_mt_is = -1;
120 static gint ett_isis_lsp_part_of_clv_mt_is = -1;
121 static gint ett_isis_lsp_clv_mt_reachable_IPv4_prefx = -1; /* CLV 235 */
122 static gint ett_isis_lsp_clv_mt_reachable_IPv6_prefx = -1; /* CLV 237 */
123 static gint ett_isis_lsp_clv_rt_capable_IPv4_prefx = -1; /* CLV 242 */
124 static gint ett_isis_lsp_clv_grp_address_IPv4_prefx = -1; /* CLV 142 */
125 static gint ett_isis_lsp_clv_mt_cap_spbv_mac_address = -1;
127 static expert_field ie_isis_lsp_checksum_bad = EI_INIT;
129 static const value_string isis_lsp_istype_vals[] = {
130 { ISIS_LSP_TYPE_UNUSED0, "Unused 0x0 (invalid)"},
131 { ISIS_LSP_TYPE_LEVEL_1, "Level 1"},
132 { ISIS_LSP_TYPE_UNUSED2, "Unused 0x2 (invalid)"},
133 { ISIS_LSP_TYPE_LEVEL_2, "Level 2"},
134 { 0, NULL } };
138 * Predclare dissectors for use in clv dissection.
140 static void dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb,
141 proto_tree *tree, int offset, int id_length, int length);
142 static void dissect_lsp_partition_dis_clv(tvbuff_t *tvb,
143 proto_tree *tree, int offset, int id_length, int length);
144 static void dissect_lsp_mt_is_reachability_clv(tvbuff_t *tvb,
145 proto_tree *tree, int offset, int id_length, int length);
146 static void dissect_lsp_ext_is_reachability_clv(tvbuff_t *tvb,
147 proto_tree *tree, int offset, int id_length, int length);
148 static void dissect_lsp_l2_is_neighbors_clv(tvbuff_t *tvb,
149 proto_tree *tree, int offset, int id_length, int length);
150 static void dissect_lsp_l1_es_neighbors_clv(tvbuff_t *tvb,
151 proto_tree *tree, int offset, int id_length, int length);
152 static void dissect_lsp_l1_is_neighbors_clv(tvbuff_t *tvb,
153 proto_tree *tree, int offset, int id_length, int length);
154 static void dissect_lsp_area_address_clv(tvbuff_t *tvb,
155 proto_tree *tree, int offset, int id_length, int length);
156 static void dissect_isis_lsp_clv_mt_cap(tvbuff_t *tvb,
157 proto_tree *tree, int offset, int id_length, int length);
158 static void dissect_lsp_authentication_clv(tvbuff_t *tvb,
159 proto_tree *tree, int offset, int id_length, int length);
160 static void dissect_lsp_ip_authentication_clv(tvbuff_t *tvb,
161 proto_tree *tree, int offset, int id_length, int length);
162 static void dissect_lsp_ipv6_int_addr_clv(tvbuff_t *tvb,
163 proto_tree *tree, int offset, int id_length, int length);
164 static void dissect_lsp_ip_int_addr_clv(tvbuff_t *tvb,
165 proto_tree *tree, int offset, int id_length, int length);
166 static void dissect_lsp_te_router_id_clv(tvbuff_t *tvb,
167 proto_tree *tree, int offset, int id_length, int length);
168 static void dissect_lsp_hostname_clv(tvbuff_t *tvb,
169 proto_tree *tree, int offset, int id_length, int length);
170 static void dissect_lsp_mt_clv(tvbuff_t *tvb,
171 proto_tree *tree, int offset, int id_length, int length);
172 static void dissect_lsp_nlpid_clv(tvbuff_t *tvb,
173 proto_tree *tree, int offset, int id_length, int length);
174 static void dissect_lsp_ipv6_reachability_clv(tvbuff_t *tvb,
175 proto_tree *tree, int offset, int id_length, int length);
176 static void dissect_lsp_ext_ip_reachability_clv(tvbuff_t *tvb,
177 proto_tree *tree, int offset, int id_length, int length);
178 static void dissect_lsp_ip_reachability_clv(tvbuff_t *tvb,
179 proto_tree *tree, int offset, int id_length, int length);
180 static void dissect_ipreach_subclv(tvbuff_t *tvb,
181 proto_tree *tree, int offset, int clv_code, int clv_len);
182 static void dissect_lsp_mt_reachable_IPv4_prefx_clv(tvbuff_t *tvb,
183 proto_tree *tree, int offset, int id_length, int length);
184 static void dissect_lsp_mt_reachable_IPv6_prefx_clv(tvbuff_t *tvb,
185 proto_tree *tree, int offset, int id_length, int length);
186 static void dissect_isis_rt_capable_clv(tvbuff_t *tvb,
187 proto_tree *tree, int offset, int id_length, int length);
188 static void dissect_isis_grp_address_clv(tvbuff_t *tvb,
189 proto_tree *tree, int offset, int id_length,int length);
190 static void fp_get_hmac_addr (guint64 hmac, guint16 *swid,
191 guint16 *sswid, guint16 *lid);
193 static const isis_clv_handle_t clv_l1_lsp_opts[] = {
195 ISIS_CLV_AREA_ADDRESS,
196 "Area address(es)",
197 &ett_isis_lsp_clv_area_addr,
198 dissect_lsp_area_address_clv
201 ISIS_CLV_IS_REACH,
202 "IS Reachability",
203 &ett_isis_lsp_clv_is_neighbors,
204 dissect_lsp_l1_is_neighbors_clv
207 ISIS_CLV_ES_NEIGHBORS,
208 "ES Neighbor(s)",
209 &ett_isis_lsp_clv_is_neighbors,
210 dissect_lsp_l1_es_neighbors_clv
213 ISIS_CLV_EXTD_IS_REACH,
214 "Extended IS reachability",
215 &ett_isis_lsp_clv_ext_is_reachability,
216 dissect_lsp_ext_is_reachability_clv
219 ISIS_CLV_INT_IP_REACH,
220 "IP Internal reachability",
221 &ett_isis_lsp_clv_ip_reachability,
222 dissect_lsp_ip_reachability_clv
225 ISIS_CLV_EXT_IP_REACH,
226 "IP External reachability",
227 &ett_isis_lsp_clv_ip_reachability,
228 dissect_lsp_ip_reachability_clv
231 ISIS_CLV_EXTD_IP_REACH,
232 "Extended IP Reachability",
233 &ett_isis_lsp_clv_ext_ip_reachability,
234 dissect_lsp_ext_ip_reachability_clv
237 ISIS_CLV_IP6_REACH,
238 "IPv6 reachability",
239 &ett_isis_lsp_clv_ipv6_reachability,
240 dissect_lsp_ipv6_reachability_clv
243 ISIS_CLV_PROTOCOLS_SUPPORTED,
244 "Protocols supported",
245 &ett_isis_lsp_clv_nlpid,
246 dissect_lsp_nlpid_clv
249 ISIS_CLV_HOSTNAME,
250 "Hostname",
251 &ett_isis_lsp_clv_hostname,
252 dissect_lsp_hostname_clv
255 ISIS_CLV_TE_ROUTER_ID,
256 "Traffic Engineering Router ID",
257 &ett_isis_lsp_clv_te_router_id,
258 dissect_lsp_te_router_id_clv
261 ISIS_CLV_IP_ADDR,
262 "IP Interface address(es)",
263 &ett_isis_lsp_clv_ipv4_int_addr,
264 dissect_lsp_ip_int_addr_clv
267 ISIS_CLV_IP6_ADDR,
268 "IPv6 Interface address(es)",
269 &ett_isis_lsp_clv_ipv6_int_addr,
270 dissect_lsp_ipv6_int_addr_clv
273 ISIS_CLV_MT_CAP,
274 "MT-Capability",
275 &ett_isis_lsp_clv_mt_cap,
276 dissect_isis_lsp_clv_mt_cap
279 ISIS_CLV_AUTHENTICATION,
280 "Authentication",
281 &ett_isis_lsp_clv_authentication,
282 dissect_lsp_authentication_clv
285 ISIS_CLV_IP_AUTHENTICATION,
286 "IP Authentication",
287 &ett_isis_lsp_clv_ip_authentication,
288 dissect_lsp_ip_authentication_clv
291 ISIS_CLV_MT_SUPPORTED,
292 "Multi Topology supported",
293 &ett_isis_lsp_clv_mt,
294 dissect_lsp_mt_clv
297 ISIS_CLV_MT_IS_REACH,
298 "Multi Topology IS Reachability",
299 &ett_isis_lsp_clv_mt_is,
300 dissect_lsp_mt_is_reachability_clv
303 ISIS_CLV_MT_IP_REACH,
304 "Multi Topology Reachable IPv4 Prefixes",
305 &ett_isis_lsp_clv_mt_reachable_IPv4_prefx,
306 dissect_lsp_mt_reachable_IPv4_prefx_clv
309 ISIS_CLV_MT_IP6_REACH,
310 "Multi Topology Reachable IPv6 Prefixes",
311 &ett_isis_lsp_clv_mt_reachable_IPv6_prefx,
312 dissect_lsp_mt_reachable_IPv6_prefx_clv
315 ISIS_CLV_RT_CAPABLE,
316 "Router Capability",
317 &ett_isis_lsp_clv_rt_capable_IPv4_prefx,
318 dissect_isis_rt_capable_clv
321 ISIS_GRP_ADDR,
322 "GROUP ADDRESS TLV",
323 &ett_isis_lsp_clv_grp_address_IPv4_prefx,
324 dissect_isis_grp_address_clv
329 NULL,
330 NULL
334 static const isis_clv_handle_t clv_l2_lsp_opts[] = {
336 ISIS_CLV_AREA_ADDRESS,
337 "Area address(es)",
338 &ett_isis_lsp_clv_area_addr,
339 dissect_lsp_area_address_clv
342 ISIS_CLV_IS_REACH,
343 "IS Reachability",
344 &ett_isis_lsp_clv_is_neighbors,
345 dissect_lsp_l2_is_neighbors_clv
348 ISIS_CLV_EXTD_IS_REACH,
349 "Extended IS reachability",
350 &ett_isis_lsp_clv_ext_is_reachability,
351 dissect_lsp_ext_is_reachability_clv
354 ISIS_CLV_PARTITION_DIS,
355 "Partition Designated Level 2 IS",
356 &ett_isis_lsp_clv_partition_dis,
357 dissect_lsp_partition_dis_clv
360 ISIS_CLV_PREFIX_NEIGHBORS,
361 "Prefix neighbors",
362 &ett_isis_lsp_clv_prefix_neighbors,
363 dissect_lsp_prefix_neighbors_clv
366 ISIS_CLV_INT_IP_REACH,
367 "IP Internal reachability",
368 &ett_isis_lsp_clv_ip_reachability,
369 dissect_lsp_ip_reachability_clv
372 ISIS_CLV_EXT_IP_REACH,
373 "IP External reachability",
374 &ett_isis_lsp_clv_ip_reachability,
375 dissect_lsp_ip_reachability_clv
378 ISIS_CLV_PROTOCOLS_SUPPORTED,
379 "Protocols supported",
380 &ett_isis_lsp_clv_nlpid,
381 dissect_lsp_nlpid_clv
384 ISIS_CLV_HOSTNAME,
385 "Hostname",
386 &ett_isis_lsp_clv_hostname,
387 dissect_lsp_hostname_clv
390 ISIS_CLV_TE_ROUTER_ID,
391 "Traffic Engineering Router ID",
392 &ett_isis_lsp_clv_te_router_id,
393 dissect_lsp_te_router_id_clv
396 ISIS_CLV_EXTD_IP_REACH,
397 "Extended IP Reachability",
398 &ett_isis_lsp_clv_ext_ip_reachability,
399 dissect_lsp_ext_ip_reachability_clv
402 ISIS_CLV_IP6_REACH,
403 "IPv6 reachability",
404 &ett_isis_lsp_clv_ipv6_reachability,
405 dissect_lsp_ipv6_reachability_clv
408 ISIS_CLV_IP_ADDR,
409 "IP Interface address(es)",
410 &ett_isis_lsp_clv_ipv4_int_addr,
411 dissect_lsp_ip_int_addr_clv
414 ISIS_CLV_IP6_ADDR,
415 "IPv6 Interface address(es)",
416 &ett_isis_lsp_clv_ipv6_int_addr,
417 dissect_lsp_ipv6_int_addr_clv
420 ISIS_CLV_MT_CAP,
421 "MT-Capability",
422 &ett_isis_lsp_clv_mt_cap,
423 dissect_isis_lsp_clv_mt_cap
426 ISIS_CLV_AUTHENTICATION,
427 "Authentication",
428 &ett_isis_lsp_clv_authentication,
429 dissect_lsp_authentication_clv
432 ISIS_CLV_IP_AUTHENTICATION,
433 "IP Authentication",
434 &ett_isis_lsp_clv_ip_authentication,
435 dissect_lsp_ip_authentication_clv
438 ISIS_CLV_MT_SUPPORTED,
439 "Multi Topology",
440 &ett_isis_lsp_clv_mt,
441 dissect_lsp_mt_clv
444 ISIS_CLV_MT_IS_REACH,
445 "Multi Topology IS Reachability",
446 &ett_isis_lsp_clv_mt_is,
447 dissect_lsp_mt_is_reachability_clv
450 ISIS_CLV_MT_IP_REACH,
451 "Multi Topology Reachable IPv4 Prefixes",
452 &ett_isis_lsp_clv_mt_reachable_IPv4_prefx,
453 dissect_lsp_mt_reachable_IPv4_prefx_clv
456 ISIS_CLV_MT_IP6_REACH,
457 "Multi Topology Reachable IPv6 Prefixes",
458 &ett_isis_lsp_clv_mt_reachable_IPv6_prefx,
459 dissect_lsp_mt_reachable_IPv6_prefx_clv
464 NULL,
465 NULL
470 static void
471 fp_get_hmac_addr (guint64 hmac, guint16 *swid, guint16 *sswid, guint16 *lid) {
473 if (!swid || !sswid || !lid) {
474 return;
477 *swid = (guint16) ((hmac & FP_HMAC_SWID_MASK) >> 32);
478 *sswid = (guint16) ((hmac & FP_HMAC_SSWID_MASK) >> 16);
479 *lid = (guint16) (hmac & FP_HMAC_LID_MASK);
482 * Name: dissect_lsp_mt_id()
484 * Description:
485 * dissect and display the multi-topology ID value
487 * Input:
488 * tvbuff_t * : tvbuffer for packet data
489 * proto_tree * : protocol display tree to fill out. CAN'T BE NULL
490 * int : offset into packet data where we are.
492 * Output:
493 * void, but we will add to proto tree.
495 static void
496 dissect_lsp_mt_id(tvbuff_t *tvb, proto_tree *tree, int offset)
498 int mt_block, mt_id;
499 const char *mt_desc="";
501 /* fetch two bytes */
502 mt_block = tvb_get_ntohs(tvb, offset);
504 proto_tree_add_text ( tree, tvb, offset, 1 ,
505 "4 most significant bits reserved, should be set to 0 (%d)", ISIS_LSP_MT_MSHIP_RES(mt_block));
507 mt_id = ISIS_LSP_MT_MSHIP_ID(mt_block);
508 /*mask out the lower 12 bits */
509 switch(mt_id) {
510 case 0:
511 mt_desc="'standard' topology";
512 break;
513 case 1:
514 mt_desc="IPv4 In-Band Management purposes";
515 break;
516 case 2:
517 mt_desc="IPv6 routing topology";
518 break;
519 case 3:
520 mt_desc="IPv4 multicast routing topology";
521 break;
522 case 4:
523 mt_desc="IPv6 multicast routing topology";
524 break;
525 default:
526 mt_desc=((mt_block & 0x0fff) < 3996) ? "Reserved for IETF Consensus" : "Development, Experimental and Proprietary features";
529 proto_tree_add_text ( tree, tvb, offset, 2 ,
530 "%s (%d)", mt_desc, mt_id);
535 * Name: dissect_metric()
537 * Description:
538 * Display a metric prefix portion. ISIS has the concept of multple
539 * metric per prefix (default, delay, expense, and error). This
540 * routine assists other dissectors by adding a single one of
541 * these to the display tree..
543 * The 8th(msbit) bit in the metric octet is the "supported" bit. The
544 * "default" support is required, so we support a "force_supported"
545 * flag that tells us that it MUST be zero (zero==supported,
546 * so it really should be a "not supported" in the boolean sense)
547 * and to display a protocol failure accordingly. Notably,
548 * Cisco IOS 12(6) blows this!
549 * The 7th bit must be zero (reserved).
551 * Input:
552 * tvbuff_t * : tvbuffer for packet data
553 * proto_tree * : protocol display tree to fill out. May be NULL
554 * int : offset into packet data where we are.
555 * guint8 : value of the metric.
556 * char * : string giving type of the metric.
557 * int : force supported. True is the supported bit MUST be zero.
559 * Output:
560 * void, but we will add to proto tree if !NULL.
562 static void
563 dissect_metric(tvbuff_t *tvb, proto_tree *tree, int offset, guint8 value,
564 const char *pstr, int force_supported )
566 int s;
568 if ( !tree ) return;
570 s = ISIS_LSP_CLV_METRIC_SUPPORTED(value);
571 proto_tree_add_text(tree, tvb, offset, 1,
572 "%s Metric: %s%s %s%d:%d", pstr,
573 s ? "Not supported" : "Supported",
574 (s && force_supported) ? "(but is required to be)":"",
575 ISIS_LSP_CLV_METRIC_RESERVED(value) ? "(reserved bit != 0)":"",
576 ISIS_LSP_CLV_METRIC_VALUE(value), value );
580 * Name: dissect_lsp_ip_reachability_clv()
582 * Description:
583 * Decode an IP reachability CLV. This can be either internal or
584 * external (the clv format does not change and which type we are
585 * displaying is put there by the dispatcher). All of these
586 * are a metric block followed by an IP addr and mask.
588 * Input:
589 * tvbuff_t * : tvbuffer for packet data
590 * proto_tree * : proto tree to build on (may be null)
591 * int : current offset into packet data
592 * int : length of IDs in packet.
593 * int : length of this clv
595 * Output:
596 * void, will modify proto_tree if not null.
598 static void
599 dissect_lsp_ip_reachability_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
600 int id_length _U_, int length)
602 proto_item *ti;
603 proto_tree *ntree = NULL;
604 guint32 src, mask, bitmask;
605 int prefix_len;
606 gboolean found_mask = FALSE;
608 while ( length > 0 ) {
609 if (length<12) {
610 isis_dissect_unknown(tvb, tree, offset,
611 "short IP reachability (%d vs 12)", length );
612 return;
615 * Gotta build a sub-tree for all our pieces
617 if ( tree ) {
618 src = tvb_get_ipv4(tvb, offset+4);
619 mask = tvb_get_ntohl(tvb, offset+8);
621 /* find out if the mask matches one of 33 possible prefix lengths */
622 bitmask = 0xffffffff;
623 for(prefix_len = 32; prefix_len >= 0; prefix_len--) {
624 if (bitmask==mask) {
625 found_mask = TRUE;
626 break;
628 bitmask = bitmask << 1;
631 /* If we have a discontiguous netmask, dump the mask, otherwise print the prefix_len */
632 /* XXX - We should probably have some sort of netmask_to_str() routine in to_str.c that does this. */
634 if(found_mask) {
635 ti = proto_tree_add_text ( tree, tvb, offset, 12,
636 "IPv4 prefix: %s/%d",
637 ip_to_str((guint8*)&src),
638 prefix_len );
639 } else {
640 ti = proto_tree_add_text ( tree, tvb, offset, 12,
641 "IPv4 prefix: %s mask %s",
642 ip_to_str((guint8*)&src),
643 tvb_ip_to_str(tvb, offset+8));
646 ntree = proto_item_add_subtree(ti,
647 ett_isis_lsp_clv_ip_reachability);
649 proto_tree_add_text (ntree, tvb, offset, 1,
650 "Default Metric: %d, %s, Distribution: %s",
651 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset)),
652 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset)) ? "External" : "Internal",
653 ISIS_LSP_CLV_METRIC_UPDOWN(tvb_get_guint8(tvb, offset)) ? "down" : "up");
656 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+1))) {
657 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: Not supported");
658 } else {
659 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: %d, %s",
660 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+1)),
661 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+1)) ? "External" : "Internal");
664 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+2))) {
665 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: Not supported");
666 } else {
667 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: %d, %s",
668 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+2)),
669 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+2)) ? "External" : "Internal");
672 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+3))) {
673 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: Not supported");
674 } else {
675 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: %d, %s",
676 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+3)),
677 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+3)) ? "External" : "Internal");
680 offset += 12;
681 length -= 12;
686 * Name: dissect_ipreach_subclv ()
688 * Description: parses IP reach subTLVs
689 * Called by various IP Reachability dissectors.
691 * Input:
692 * tvbuff_t * : tvbuffer for packet data
693 * proto_tree * : protocol display tree to fill out.
694 * int : offset into packet data where we are (beginning of the sub_clv value).
696 * Output:
697 * void
699 static void
700 dissect_ipreach_subclv(tvbuff_t *tvb, proto_tree *tree, int offset, int clv_code, int clv_len)
703 switch (clv_code) {
704 case 1:
705 while (clv_len >= 4) {
706 proto_tree_add_text(tree, tvb, offset, 4,
707 "32-Bit Administrative tag: 0x%08x (=%u)",
708 tvb_get_ntohl(tvb, offset),
709 tvb_get_ntohl(tvb, offset));
710 offset+=4;
711 clv_len-=4;
713 break;
714 case 2:
715 while (clv_len >= 8) {
716 proto_tree_add_text(tree, tvb, offset, 8,
717 "64-Bit Administrative tag: 0x%08x%08x",
718 tvb_get_ntohl(tvb, offset),
719 tvb_get_ntohl(tvb, offset+4));
720 offset+=8;
721 clv_len-=8;
723 break;
725 default :
726 proto_tree_add_text (tree, tvb, offset, clv_len+2,
727 "Unknown sub-TLV: code %u, length %u",
728 clv_code, clv_len );
729 break;
735 * Name: dissect_lsp_ext_ip_reachability_clv()
737 * Description: Decode an Extended IP Reachability CLV - code 135.
739 * The extended IP reachability TLV is an extended version
740 * of the IP reachability TLVs (codes 128 and 130). It encodes
741 * the metric as a 32-bit unsigned interger and allows to add
742 * sub-CLV(s).
744 * CALLED BY TLV 235 DISSECTOR
747 * Input:
748 * tvbuff_t * : tvbuffer for packet data
749 * proto_tree * : proto tree to build on (may be null)
750 * int : current offset into packet data
751 * int : length of IDs in packet.
752 * int : length of this clv
754 * Output:
755 * void, will modify proto_tree if not null.
757 static void
758 dissect_lsp_ext_ip_reachability_clv(tvbuff_t *tvb, proto_tree *tree,
759 int offset, int id_length _U_, int length)
761 proto_item *pi = NULL;
762 proto_tree *subtree = NULL;
763 proto_tree *subtree2 = NULL;
764 guint8 ctrl_info;
765 guint bit_length;
766 int byte_length;
767 guint8 prefix [4];
768 guint32 metric;
769 guint len,i;
770 guint subclvs_len;
771 guint clv_code, clv_len;
773 if (!tree) return;
775 while (length > 0) {
776 ctrl_info = tvb_get_guint8(tvb, offset+4);
777 bit_length = ctrl_info & 0x3f;
778 byte_length = ipv4_addr_and_mask(tvb, offset+5, prefix, bit_length);
779 if (byte_length == -1) {
780 isis_dissect_unknown(tvb, tree, offset,
781 "IPv4 prefix has an invalid length: %d bits", bit_length );
782 return;
784 metric = tvb_get_ntohl(tvb, offset);
785 subclvs_len = 0;
786 if ((ctrl_info & 0x40) != 0)
787 subclvs_len = 1+tvb_get_guint8(tvb, offset+5+byte_length);
789 pi = proto_tree_add_text (tree, tvb, offset, 5+byte_length+subclvs_len,
790 "IPv4 prefix: %s/%d, Metric: %u, Distribution: %s, %ssub-TLVs present",
791 ip_to_str (prefix),
792 bit_length,
793 metric,
794 ((ctrl_info & 0x80) == 0) ? "up" : "down",
795 ((ctrl_info & 0x40) == 0) ? "no " : "" );
797 /* open up a new tree per prefix */
798 subtree = proto_item_add_subtree (pi, ett_isis_lsp_part_of_clv_ext_ip_reachability);
800 proto_tree_add_text (subtree, tvb, offset+5, byte_length, "IPv4 prefix: %s/%u",
801 ip_to_str (prefix), bit_length);
803 proto_tree_add_text (subtree, tvb, offset, 4, "Metric: %u", metric);
805 proto_tree_add_text (subtree, tvb, offset+4, 1, "Distribution: %s",
806 ((ctrl_info & 0x80) == 0) ? "up" : "down");
808 len = 5 + byte_length;
809 if ((ctrl_info & 0x40) != 0) {
810 subclvs_len = tvb_get_guint8(tvb, offset+len);
811 pi = proto_tree_add_text (subtree, tvb, offset+len, 1, "sub-TLVs present, total length: %u bytes",
812 subclvs_len);
813 proto_item_set_len (pi, subclvs_len+1);
814 /* open up a new tree for the subTLVs */
815 subtree2 = proto_item_add_subtree (pi, ett_isis_lsp_clv_ip_reach_subclv);
817 i =0;
818 while (i < subclvs_len) {
819 clv_code = tvb_get_guint8(tvb, offset+len+1); /* skip the total subtlv len indicator */
820 clv_len = tvb_get_guint8(tvb, offset+len+2);
823 * we pass on now the raw data to the ipreach_subtlv dissector
824 * therefore we need to skip 3 bytes
825 * (total subtlv len, subtlv type, subtlv len)
827 dissect_ipreach_subclv(tvb, subtree2, offset+len+3, clv_code, clv_len);
828 i += clv_len + 2;
830 len += 1 + subclvs_len;
831 } else {
832 proto_tree_add_text (subtree, tvb, offset+4, 1, "no sub-TLVs present");
833 proto_item_set_len (pi, len);
836 offset += len;
837 length -= len;
842 * Name: dissect_isis_grp_address_clv()
844 * Description: Decode GROUP ADDRESS subTLVs
845 * The Group Address TLV is composed of 1 octet for the type,
846 * 1 octet that specifies the number of bytes in the value field, and a
847 * Variable length value field that can have any or all of the subTLVs that are listed in the
848 * - below section
850 *Input:
851 * tvbuff_t * : tvbuffer for packet data
852 * proto_tree * : proto tree to build on (may be null)
853 * int : current offset into packet data
854 * int : length of IDs in packet.
855 * int : length of this clv
857 * Output:
858 * void, will modify proto_tree if not null.
861 static void
862 dissect_isis_grp_address_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
863 int tree_id,int length)
865 gint len;
866 gint record_num;
867 gint source_num;
868 gint k=1;
869 guint16 mt_block;
870 guint64 hmac_src;
871 guint16 swid = 0;
872 guint16 sswid = 0;
873 guint16 lid = 0;
875 proto_item *ti=NULL;
876 proto_tree *rt_tree=NULL;
878 const char *mt_desc;
881 while (length>0) {
882 /* fetch two bytes */
883 mt_block=tvb_get_ntohs(tvb, offset);
884 /* Mask out the lower 8 bits */
885 switch((mt_block&0xff00)>>8) {
888 case GRP_MAC_ADDRESS:
889 mt_desc="GROUP MAC ADDRESS";
891 ti = proto_tree_add_text (tree, tvb, offset,(mt_block&0x00ff)+2 , "%s SUB TLV", mt_desc);
892 rt_tree = proto_item_add_subtree(ti,ett_isis_lsp_clv_grp_address_IPv4_prefx);
894 length=length-1;
895 offset=offset+1;
897 len=tvb_get_guint8(tvb, offset);/* 1 byte fetched displays the length*/
898 proto_tree_add_text (rt_tree, tvb, offset,1," Length :%d ",len);
900 if(len < 5) {
901 length=length-len;
902 offset=offset+len;
903 break;
906 length=length-1;
907 offset=offset+1;
910 mt_block=tvb_get_ntohs(tvb, offset);/* Fetch the data in the next two bytes for display*/
911 proto_tree_add_text (rt_tree, tvb, offset,2," Topology ID:%d ",(mt_block&0x0fff) );
914 length=length-2;
915 offset=offset+2;
916 len=len-2;
918 mt_block=tvb_get_ntohs(tvb, offset);/* Fetch the data in the next two bytes for display*/
919 proto_tree_add_text (rt_tree,tvb, offset,2," VLAN ID:%d ",(mt_block&0x0fff) );
921 length=length-2;
922 offset=offset+2;
923 len=len-2;
925 record_num=tvb_get_guint8(tvb, offset);/* 1 byte fetched displays the length*/
926 proto_tree_add_text (rt_tree,tvb, offset,1, " Number of records :%d ",record_num);
928 length=length-1;
929 offset=offset+1;
930 len=len-1;
932 while(len > 0) {
934 source_num=tvb_get_guint8(tvb, offset);
935 proto_tree_add_text (rt_tree,tvb, offset,1," Number of sources :%d ",source_num);
937 length=length-1;
938 offset=offset+1;
939 len=len-1;
941 hmac_src=tvb_get_ntoh48(tvb, offset);/* Fetch the data in the next two bytes for display*/
943 fp_get_hmac_addr (hmac_src, &swid, &sswid, &lid);
944 proto_tree_add_text (rt_tree,tvb, offset,6," Group Address:%04x.%04x.%04x ",swid, sswid, lid );
946 length=length-6;
947 offset=offset+6;
948 len=len-6;
950 while((len > 0) && (source_num > 0)) {
951 hmac_src = tvb_get_ntoh48 (tvb, offset);
952 fp_get_hmac_addr (hmac_src, &swid, &sswid, &lid);
953 proto_tree_add_text (rt_tree,tvb, offset,6," Source Address (%d):%04x.%04x.%04x",k,swid, sswid, lid);
955 k=k+1;
956 length=length-6;
957 offset=offset+6;
958 len=len-6;
959 source_num--;
963 break;
966 default:
967 mt_desc="INVALID";
968 proto_tree_add_uint_format ( tree, tree_id, tvb, offset,(mt_block&0x00ff)+2,
969 mt_block,
970 "%s SUB TLV",mt_desc );
971 offset=offset+1;
972 length=length-2-(tvb_get_guint8(tvb, offset));
973 offset=offset+1+(tvb_get_guint8(tvb, offset));
974 break;
980 * Name: dissect_isis_rt_capable_clv()
982 * Description: Decode RouterCapability subTLVs
984 * The Router Capability TLV is composed of 1 octet for the type,
985 * 1 octet that specifies the number of bytes in the value field, and a
986 * variable length value field that can have any or all of the subTLVs
987 * that are listed in the below section
989 * Input:
990 * tvbuff_t * : tvbuffer for packet data
991 * proto_tree * : proto tree to build on (may be null)
992 * int : current offset into packet data
993 * int : length of IDs in packet.
994 * int : length of this clv
995 * len : local variable described to handle the length of the subTLV
997 * Output:
998 * void, will modify proto_tree if not null.
1001 /* As per RFC 6326 section 2.3 */
1002 static void
1003 dissect_isis_rt_capable_clv(tvbuff_t *tvb,
1004 proto_tree *tree, int offset, int id_length _U_, int length)
1006 gint len;
1007 guint16 rt_block;
1008 guint32 rt_block1;
1009 proto_item *ti;
1010 proto_tree *rt_tree;
1012 const char *mt_desc;
1013 gint root_id = 1; /* To display the root id */
1014 gint sec_vlan_id = 1; /* To display the seconadary VLAN id */
1015 length = length - 5; /* Ignoring the 5 reserved bytes */
1016 offset = offset + 5;
1018 while (length>1) {
1019 /* fetch two bytes */
1020 rt_block = tvb_get_ntohs(tvb, offset);
1022 /* Mask out the lower 8 bits */
1023 switch ((rt_block&0xff00)>>8) {
1025 case TRILL_VERSION:
1026 mt_desc = "TRILL version";
1028 ti = proto_tree_add_text(tree, tvb, offset, (rt_block&0x00ff)+2, "%s sub tlv", mt_desc);
1030 rt_tree = proto_item_add_subtree(ti, ett_isis_lsp_clv_rt_capable_IPv4_prefx);
1032 length = length-1;
1033 offset = offset+1;
1035 len = tvb_get_guint8(tvb, offset); /* 1 byte fetched displays the length */
1036 proto_tree_add_text(rt_tree, tvb, offset, 1, "Length: %d", len);
1038 rt_block = tvb_get_ntohs(tvb, offset); /* Fetch the data in the next two bytes for display */
1039 proto_tree_add_text(rt_tree, tvb, offset+1, 1, "Maximum version: %d", (rt_block&0x00ff));
1041 length = length-2;
1042 offset = offset+2;
1044 break;
1046 case TREES:
1047 mt_desc = "Trees";
1048 ti = proto_tree_add_text(tree, tvb, offset, (rt_block&0x00ff)+2, "%s sub tlv", mt_desc);
1050 rt_tree = proto_item_add_subtree(ti, ett_isis_lsp_clv_rt_capable_IPv4_prefx);
1052 length = length-1;
1053 offset = offset+1;
1055 len = tvb_get_guint8(tvb, offset);
1056 proto_tree_add_text(rt_tree, tvb, offset, 1, "Length: %d", len);
1058 length = length-1;
1059 offset = offset+1;
1061 rt_block = tvb_get_ntohs(tvb, offset);
1062 proto_tree_add_text(rt_tree, tvb, offset, 2, "Nof. trees to compute: %d", rt_block);
1064 length = length-2;
1065 offset = offset+2;
1067 rt_block = tvb_get_ntohs(tvb, offset);
1068 proto_tree_add_text(rt_tree, tvb, offset, 2, "Maximum nof. trees to compute: %d", rt_block);
1070 length = length-2;
1071 offset = offset+2;
1073 rt_block = tvb_get_ntohs(tvb, offset);
1075 proto_tree_add_text(rt_tree, tvb, offset, 2, "Nof. trees to use: %d", rt_block);
1077 length = length-2;
1078 offset = offset+2;
1080 break;
1082 case TREE_IDENTIFIER:
1083 mt_desc = "Tree root identifier";
1084 ti=proto_tree_add_text(tree, tvb, offset, (rt_block&0x00ff)+2, "%s sub tlv", mt_desc);
1086 rt_tree = proto_item_add_subtree(ti, ett_isis_lsp_clv_rt_capable_IPv4_prefx);
1088 length = length-1;
1089 offset = offset+1;
1091 len = tvb_get_guint8(tvb, offset);
1092 proto_tree_add_text(rt_tree, tvb, offset, 1, "Length: %d", len);
1094 rt_block = tvb_get_ntohs(tvb, offset+1);
1096 proto_tree_add_text(rt_tree, tvb, offset+1, 2, "Starting tree no: %d", rt_block);
1098 len = len-2;
1099 length = length-2;
1100 offset = offset+3;
1102 while (len>1) {
1103 rt_block = tvb_get_ntohs(tvb, offset);
1104 proto_tree_add_text(rt_tree, tvb, offset, 2, "Nickname(%dth root): %d", root_id, rt_block);
1105 root_id = root_id+1;
1106 len = len-2;
1107 length = length-2;
1108 offset = offset+2;
1110 break;
1112 case NICKNAME:
1113 mt_desc = "The nickname";
1114 ti=proto_tree_add_text(tree, tvb, offset, (rt_block&0x00ff)+2, "%s sub tlv", mt_desc);
1116 rt_tree = proto_item_add_subtree(ti, ett_isis_lsp_clv_rt_capable_IPv4_prefx);
1118 length = length-1;
1119 offset = offset+1;
1120 len = tvb_get_guint8(tvb, offset);
1122 proto_tree_add_text(rt_tree, tvb, offset, 1, "Length: %d", len);
1123 length = length-1;
1124 offset = offset+1;
1126 while (len>0) {
1127 rt_block = tvb_get_ntohs(tvb, offset);
1129 proto_tree_add_text(rt_tree, tvb, offset, 1, "Nickname priority: %d", ((rt_block&0xff00)>>8));
1131 length = length-1;
1132 offset = offset+1;
1133 len = len-1;
1134 rt_block = tvb_get_ntohs(tvb, offset);
1136 proto_tree_add_text(rt_tree, tvb, offset, 2, "Tree root priority: %d", rt_block);
1138 length = length-2;
1139 offset = offset+2;
1140 len = len-2;
1142 rt_block = tvb_get_ntohs(tvb, offset);
1144 proto_tree_add_text(rt_tree, tvb, offset, 2, "Nickname: %x", rt_block);
1146 length = length-2;
1147 offset = offset+2;
1148 len = len-2;
1150 break;
1152 case INTERESTED_VLANS:
1153 mt_desc = "Interested VLAN and spanning tree root";
1154 ti = proto_tree_add_text(tree, tvb, offset, (rt_block&0x00ff)+2, "%s sub tlv", mt_desc);
1156 rt_tree = proto_item_add_subtree(ti, ett_isis_lsp_clv_rt_capable_IPv4_prefx);
1158 length = length-1;
1159 offset = offset+1;
1161 len = tvb_get_guint8(tvb, offset);
1162 proto_tree_add_text(rt_tree, tvb, offset, 1, "Length: %d", len);
1164 length = length-1;
1165 offset = offset+1;
1166 len = len-1;
1168 rt_block = tvb_get_ntohs(tvb, offset);
1170 proto_tree_add_text(rt_tree, tvb, offset, 2, "Nickname: %x", rt_block);
1172 length = length-2;
1173 offset = offset+2;
1174 len = len-2;
1176 rt_block = tvb_get_ntohs(tvb, offset);
1178 proto_tree_add_text(rt_tree, tvb, offset, 2,
1179 "%s%s", (rt_block&0x8000) ? "IPv4 multicast router set, " : "IPv4 multicast router not set, ",
1180 (rt_block&0x4000) ? "IPv6 multicast router set" : "IPv6 multicast router not set");
1181 proto_tree_add_text(rt_tree, tvb, offset, 2, "Vlan start id: %x", (rt_block&0x0fff));
1183 length = length-2;
1184 offset = offset+2;
1185 len = len-2;
1187 rt_block = tvb_get_ntohs(tvb, offset);
1189 proto_tree_add_text(rt_tree, tvb, offset, 2, "Vlan end id: %x", (rt_block&0x0fff));
1191 length = length-2;
1192 offset = offset+2;
1193 len = len-2;
1195 rt_block1 = tvb_get_ntohl(tvb, offset);
1197 proto_tree_add_text(rt_tree, tvb, offset, 4, "Appointed forward state lost counter: %d", rt_block1);
1199 length = length-4;
1200 offset = offset+4;
1201 len = len-4;
1203 while (len>0) {
1204 proto_tree_add_item(rt_tree, hf_isis_lsp_root_id, tvb, offset, 6, ENC_BIG_ENDIAN);
1206 length = length-6;
1207 offset = offset+6;
1208 len = len-6;
1209 length = length-2;
1211 break;
1213 case TREES_USED_IDENTIFIER:
1214 mt_desc = "Trees used identifier";
1216 ti=proto_tree_add_text(tree, tvb, offset, (rt_block&0x00ff)+2, "%s sub tlv", mt_desc);
1218 rt_tree = proto_item_add_subtree(ti, ett_isis_lsp_clv_rt_capable_IPv4_prefx);
1220 length = length-1;
1221 offset = offset+1;
1223 len = tvb_get_guint8(tvb, offset);
1224 proto_tree_add_text(rt_tree, tvb, offset, 1, "Length: %d", len);
1226 rt_block = tvb_get_ntohs(tvb, offset+1);
1228 proto_tree_add_text(rt_tree, tvb, offset+1, 2, "Starting tree no: %d", rt_block);
1229 len = len-2;
1230 length = length-2;
1231 offset = offset+3;
1232 root_id = 1;
1234 while (len>0) {
1235 rt_block = tvb_get_ntohs(tvb, offset);
1236 proto_tree_add_text(rt_tree, tvb, offset,2,"Nickname(%dth root): %d", root_id, rt_block);
1237 root_id = root_id+1;
1239 len = len-2;
1240 offset = offset+2;
1241 length = length-2;
1243 break;
1245 case VLAN_GROUP:
1246 mt_desc = "The VLAN group";
1247 ti = proto_tree_add_text(tree, tvb, offset, (rt_block&0x00ff)+2, "%s sub tlv", mt_desc);
1249 rt_tree = proto_item_add_subtree(ti, ett_isis_lsp_clv_rt_capable_IPv4_prefx);
1251 length = length-1;
1252 offset = offset+1;
1254 len = tvb_get_guint8(tvb, offset);
1255 proto_tree_add_text(rt_tree, tvb, offset, 1, "Length: %d", len);
1257 len = len-1;
1258 length = length-1;
1259 offset = offset+1;
1261 rt_block = tvb_get_ntohs(tvb, offset);
1262 proto_tree_add_text(rt_tree, tvb, offset, 2, "Primary vlan id: %d", (rt_block&0x0fff));
1264 length = length-2;
1265 offset = offset+2;
1266 len = len-2;
1268 rt_block = tvb_get_ntohs(tvb, offset);
1269 proto_tree_add_text(rt_tree, tvb, offset, 2, "Secondary vlan id: %d", (rt_block&0x0fff));
1271 length = length-2;
1272 offset = offset+2;
1273 len = len-2;
1274 sec_vlan_id = 1;
1276 while (len>0) {
1277 rt_block = tvb_get_ntohs(tvb, offset);
1279 proto_tree_add_text(rt_tree, tvb, offset, 2, "%dth secondary vlan id: %x", sec_vlan_id, rt_block);
1281 length = length-2;
1282 offset = offset+2;
1283 sec_vlan_id = sec_vlan_id+1;
1284 len = len-2;
1286 break;
1288 default:
1289 mt_desc = "INVALID";
1290 proto_tree_add_text(tree, tvb, offset, (rt_block&0x00ff)+2, "%s sub tlv", mt_desc);
1292 offset = offset+1;
1293 length = length-2-(tvb_get_guint8(tvb, offset));
1294 offset = offset+1+(tvb_get_guint8(tvb, offset));
1295 break;
1304 * Name: dissect_lsp_ipv6_reachability_clv()
1306 * Description: Decode an IPv6 reachability CLV - code 236.
1308 * CALLED BY TLV 237 DISSECTOR
1310 * Input:
1311 * tvbuff_t * : tvbuffer for packet data
1312 * proto_tree * : proto tree to build on (may be null)
1313 * int : current offset into packet data
1314 * int : length of IDs in packet.
1315 * int : length of this clv
1317 * Output:
1318 * void, will modify proto_tree if not null.
1320 static void
1321 dissect_lsp_ipv6_reachability_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1322 int id_length _U_, int length)
1324 proto_item *pi;
1325 proto_tree *subtree = NULL;
1326 proto_tree *subtree2 = NULL;
1327 guint8 ctrl_info;
1328 guint bit_length;
1329 int byte_length;
1330 struct e_in6_addr prefix;
1331 guint32 metric;
1332 guint len,i;
1333 guint subclvs_len;
1334 guint clv_code, clv_len;
1336 if (!tree) return;
1338 while (length > 0) {
1339 ctrl_info = tvb_get_guint8(tvb, offset+4);
1340 bit_length = tvb_get_guint8(tvb, offset+5);
1341 byte_length = ipv6_addr_and_mask(tvb, offset+6, &prefix, bit_length);
1342 if (byte_length == -1) {
1343 isis_dissect_unknown(tvb, tree, offset,
1344 "IPv6 prefix has an invalid length: %d bits", bit_length );
1345 return;
1347 metric = tvb_get_ntohl(tvb, offset);
1348 subclvs_len = 0;
1349 if ((ctrl_info & 0x20) != 0)
1350 subclvs_len = 1+tvb_get_guint8(tvb, offset+6+byte_length);
1352 pi = proto_tree_add_text (tree, tvb, offset, 6+byte_length+subclvs_len,
1353 "IPv6 prefix: %s/%u, Metric: %u, Distribution: %s, %s, %ssub-TLVs present",
1354 ip6_to_str (&prefix),
1355 bit_length,
1356 metric,
1357 ((ctrl_info & 0x80) == 0) ? "up" : "down",
1358 ((ctrl_info & 0x40) == 0) ? "internal" : "external",
1359 ((ctrl_info & 0x20) == 0) ? "no " : "" );
1361 subtree = proto_item_add_subtree (pi, ett_isis_lsp_part_of_clv_ipv6_reachability);
1363 proto_tree_add_text (subtree, tvb, offset+6, byte_length, "IPv6 prefix: %s/%u",
1364 ip6_to_str (&prefix),
1365 bit_length);
1367 proto_tree_add_text (subtree, tvb, offset, 4,
1368 "Metric: %u", metric);
1370 proto_tree_add_text (subtree, tvb, offset+4, 1,
1371 "Distribution: %s, %s",
1372 ((ctrl_info & 0x80) == 0) ? "up" : "down",
1373 ((ctrl_info & 0x40) == 0) ? "internal" : "external" );
1375 if ((ctrl_info & 0x1f) != 0) {
1376 proto_tree_add_text (subtree, tvb, offset+4, 1,
1377 "Reserved bits: 0x%x",
1378 (ctrl_info & 0x1f) );
1381 len = 6 + byte_length;
1382 if ((ctrl_info & 0x20) != 0) {
1383 subclvs_len = tvb_get_guint8(tvb, offset+len);
1384 pi = proto_tree_add_text (subtree, tvb, offset+len, 1, "sub-TLVs present, total length: %u bytes",
1385 subclvs_len);
1386 proto_item_set_len (pi, subclvs_len+1);
1387 /* open up a new tree for the subTLVs */
1388 subtree2 = proto_item_add_subtree (pi, ett_isis_lsp_clv_ip_reach_subclv);
1390 i =0;
1391 while (i < subclvs_len) {
1392 clv_code = tvb_get_guint8(tvb, offset+len+1); /* skip the total subtlv len indicator */
1393 clv_len = tvb_get_guint8(tvb, offset+len+2);
1394 dissect_ipreach_subclv(tvb, subtree2, offset+len+3, clv_code, clv_len);
1395 i += clv_len + 2;
1397 len += 1 + subclvs_len;
1398 } else {
1399 proto_tree_add_text (subtree, tvb, offset+4, 1, "no sub-TLVs present");
1400 proto_item_set_len (pi, len);
1402 offset += len;
1403 length -= len;
1408 * Name: dissect_lsp_nlpid_clv()
1410 * Description:
1411 * Decode for a lsp packets NLPID clv. Calls into the
1412 * clv common one.
1414 * Input:
1415 * tvbuff_t * : tvbuffer for packet data
1416 * proto_tree * : proto tree to build on (may be null)
1417 * int : current offset into packet data
1418 * int : length of IDs in packet.
1419 * int : length of this clv
1421 * Output:
1422 * void, will modify proto_tree if not null.
1424 static void
1425 dissect_lsp_nlpid_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1426 int id_length _U_, int length)
1428 isis_dissect_nlpid_clv(tvb, tree, offset, length);
1432 * Name: dissect_lsp_mt_clv()
1434 * Description: - code 229
1435 * Decode for a lsp packets Multi Topology clv. Calls into the
1436 * clv common one.
1438 * Input:
1439 * tvbuff_t * : tvbuffer for packet data
1440 * proto_tree * : proto tree to build on (may be null)
1441 * int : current offset into packet data
1442 * guint : length of this clv
1443 * int : length of IDs in packet.
1445 * Output:
1446 * void, will modify proto_tree if not null.
1448 static void
1449 dissect_lsp_mt_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1450 int id_length _U_, int length)
1452 isis_dissect_mt_clv(tvb, tree, offset, length, hf_isis_lsp_clv_mt );
1456 * Name: dissect_lsp_hostname_clv()
1458 * Description:
1459 * Decode for a lsp packets hostname clv. Calls into the
1460 * clv common one.
1462 * Input:
1463 * tvbuff_t * : tvbuffer for packet data
1464 * proto_tree * : proto tree to build on (may be null)
1465 * int : current offset into packet data
1466 * int : length of IDs in packet.
1467 * int : length of this clv
1469 * Output:
1470 * void, will modify proto_tree if not null.
1472 static void
1473 dissect_lsp_hostname_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1474 int id_length _U_, int length)
1476 isis_dissect_hostname_clv(tvb, tree, offset, length,
1477 hf_isis_lsp_hostname);
1482 * Name: dissect_lsp_te_router_id_clv()
1484 * Description:
1485 * Decode for a lsp packets Traffic Engineering ID clv. Calls into the
1486 * clv common one.
1488 * Input:
1489 * tvbuff_t * : tvbuffer for packet data
1490 * proto_tree * : proto tree to build on (may be null)
1491 * int : current offset into packet data
1492 * int : length of IDs in packet.
1493 * int : length of this clv
1495 * Output:
1496 * void, will modify proto_tree if not null.
1498 static void
1499 dissect_lsp_te_router_id_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1500 int id_length _U_, int length)
1502 isis_dissect_te_router_id_clv(tvb, tree, offset, length,
1503 hf_isis_lsp_clv_te_router_id );
1508 * Name: dissect_lsp_ip_int_addr_clv()
1510 * Description:
1511 * Decode for a lsp packets ip interface addr clv. Calls into the
1512 * clv common one.
1514 * Input:
1515 * tvbuff_t * : tvbuffer for packet data
1516 * proto_tree * : proto tree to build on (may be null)
1517 * int : current offset into packet data
1518 * int : length of IDs in packet.
1519 * int : length of this clv
1521 * Output:
1522 * void, will modify proto_tree if not null.
1524 static void
1525 dissect_lsp_ip_int_addr_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1526 int id_length _U_, int length)
1528 isis_dissect_ip_int_clv(tvb, tree, offset, length,
1529 hf_isis_lsp_clv_ipv4_int_addr );
1533 * Name: dissect_lsp_ipv6_int_addr_clv()
1535 * Description: Decode an IPv6 interface addr CLV - code 232.
1537 * Calls into the clv common one.
1539 * Input:
1540 * tvbuff_t * : tvbuffer for packet data
1541 * proto_tree * : proto tree to build on (may be null)
1542 * int : current offset into packet data
1543 * int : length of IDs in packet.
1544 * int : length of this clv
1546 * Output:
1547 * void, will modify proto_tree if not null.
1549 static void
1550 dissect_lsp_ipv6_int_addr_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1551 int id_length _U_, int length)
1553 isis_dissect_ipv6_int_clv(tvb, tree, offset, length,
1554 hf_isis_lsp_clv_ipv6_int_addr );
1557 static void
1558 dissect_isis_lsp_clv_mt_cap_spb_instance(tvbuff_t *tvb,
1559 proto_tree *tree, int offset, int subtype, int sublen)
1561 const int CIST_ROOT_ID_LEN = 8; /* CIST Root Identifier */
1562 const int CIST_EXT_ROOT_PATH_COST_LEN = 4; /* CIST External Root Path Cost */
1563 const int BRIDGE_PRI_LEN = 2; /* Bridge Priority */
1564 const int V_SPSOURCEID_LEN = 4; /* v | SPSourceID */
1565 const int NUM_TREES_LEN = 1; /* num of trees */
1567 const int CIST_ROOT_ID_OFFSET = 0;
1568 const int CIST_EXT_ROOT_PATH_COST_OFFSET = CIST_ROOT_ID_OFFSET + CIST_ROOT_ID_LEN;
1569 const int BRIDGE_PRI_OFFSET = CIST_EXT_ROOT_PATH_COST_OFFSET + CIST_EXT_ROOT_PATH_COST_LEN;
1570 const int V_SPSOURCEID_OFFSET = BRIDGE_PRI_OFFSET + BRIDGE_PRI_LEN;
1571 const int NUM_TREES_OFFSET = V_SPSOURCEID_OFFSET + V_SPSOURCEID_LEN;
1572 const int FIXED_LEN = NUM_TREES_OFFSET + NUM_TREES_LEN;
1573 const int VLAN_ID_TUPLE_LEN = 8;
1575 if (sublen < FIXED_LEN) {
1576 isis_dissect_unknown( tvb, tree, offset,
1577 "Short SPB Digest subTLV (%d vs %d)", sublen, FIXED_LEN);
1578 return;
1580 else {
1581 proto_tree *subtree, *ti;
1582 int subofs = offset;
1583 const guint8 *cist_root_identifier = tvb_get_ptr (tvb, subofs + CIST_ROOT_ID_OFFSET, CIST_ROOT_ID_LEN);
1584 const guint32 cist_root_path_cost = tvb_get_ntohl (tvb, subofs + CIST_EXT_ROOT_PATH_COST_OFFSET);
1585 const guint16 bridge_priority = tvb_get_ntohs (tvb, subofs + BRIDGE_PRI_OFFSET);
1586 const guint32 v_spsourceid = tvb_get_ntohl (tvb, subofs + V_SPSOURCEID_OFFSET);
1587 guint8 num_trees = tvb_get_guint8(tvb, subofs + NUM_TREES_OFFSET);
1589 /*************************/
1590 ti = proto_tree_add_text( tree, tvb, offset-2, sublen+2,
1591 "SPB Instance: Type: 0x%02x, Length: %d", subtype, sublen);
1592 subtree = proto_item_add_subtree(ti, ett_isis_lsp_clv_mt_cap_spb_instance);
1594 /*************************/
1595 proto_tree_add_text( subtree, tvb, subofs + CIST_ROOT_ID_OFFSET, CIST_ROOT_ID_LEN,
1596 "CIST Root Identifier: %08x-%08x-%08x-%08x-%08x-%08x-%08x-%08x",
1597 cist_root_identifier[0],
1598 cist_root_identifier[1],
1599 cist_root_identifier[2],
1600 cist_root_identifier[3],
1601 cist_root_identifier[4],
1602 cist_root_identifier[5],
1603 cist_root_identifier[6],
1604 cist_root_identifier[7]);
1605 proto_tree_add_text( subtree, tvb, subofs + CIST_EXT_ROOT_PATH_COST_OFFSET, CIST_EXT_ROOT_PATH_COST_LEN,
1606 "CIST External Root Path Cost: 0x%08x (%u)",
1607 cist_root_path_cost,
1608 cist_root_path_cost);
1609 proto_tree_add_text( subtree, tvb, subofs + BRIDGE_PRI_OFFSET, BRIDGE_PRI_LEN,
1610 "Bridge Priority: 0x%04x (%u)",
1611 bridge_priority,
1612 bridge_priority);
1613 proto_tree_add_text( subtree, tvb, subofs + V_SPSOURCEID_OFFSET, V_SPSOURCEID_LEN,
1614 "V: %u, SPSourceId: 0x%05x (%u)",
1615 (v_spsourceid & (1 << 20)) ? 1 : 0,
1616 v_spsourceid & 0xfffff,
1617 v_spsourceid & 0xfffff);
1618 proto_tree_add_text( subtree, tvb, subofs + NUM_TREES_OFFSET, NUM_TREES_LEN,
1619 "Number of Trees: 0x%02x (%u)%s",
1620 num_trees,
1621 num_trees,
1622 num_trees ? "" : " Invalid subTLV: zero trees");
1624 subofs += FIXED_LEN;
1625 sublen -= FIXED_LEN;
1627 /*************************/
1628 if (sublen != (num_trees * VLAN_ID_TUPLE_LEN)) {
1629 proto_tree_add_text( subtree, tvb, subofs, 0,
1630 "SubTLV length doesn't match number of trees");
1631 return;
1633 while (sublen > 0 && num_trees > 0) {
1634 if (sublen < VLAN_ID_TUPLE_LEN) {
1635 isis_dissect_unknown( tvb, subtree, offset,
1636 "Short VLAN_ID entry (%d vs %d)", sublen, VLAN_ID_TUPLE_LEN);
1637 return;
1639 else {
1640 const guint8 flags = tvb_get_guint8(tvb, subofs);
1641 const guint8 *ect_id = tvb_get_ptr(tvb, subofs + 1, 4);
1642 const guint8 *bvid_spvid = tvb_get_ptr(tvb, subofs + 1 + 4, 3);
1643 const guint16 bvid = (0xff0 & (((guint16)bvid_spvid[0]) << 4)) | (0x0f & (bvid_spvid[1] >> 4));
1644 const guint16 spvid = (0xf00 & (((guint16)bvid_spvid[1]) << 8)) | (0xff & (bvid_spvid[2]));
1645 proto_tree_add_text( subtree, tvb, subofs, VLAN_ID_TUPLE_LEN,
1646 " U: %u, M: %u, A: %u, ECT: %02x-%02x-%02x-%02x, BVID: 0x%03x (%d),%s SPVID: 0x%03x (%d)",
1647 (flags >> 7) & 1,
1648 (flags >> 6) & 1,
1649 (flags >> 5) & 1,
1650 ect_id[0], ect_id[1], ect_id[2], ect_id[3],
1651 bvid, bvid,
1652 ( bvid < 10 ? " "
1653 : bvid < 100 ? " "
1654 : bvid < 1000 ? " "
1655 : ""),
1656 spvid, spvid);
1657 subofs += VLAN_ID_TUPLE_LEN;
1658 sublen -= VLAN_ID_TUPLE_LEN;
1659 --num_trees;
1662 if (num_trees) {
1663 isis_dissect_unknown( tvb, subtree, offset,
1664 "Short subTLV (%d vs %d)", sublen, num_trees * VLAN_ID_TUPLE_LEN);
1665 return;
1669 static void
1670 dissect_isis_lsp_clv_mt_cap_spb_oalg(tvbuff_t *tvb,
1671 proto_tree *tree, int offset, int subtype, int sublen)
1673 isis_dissect_unknown( tvb, tree, offset,
1674 "MT-Cap SPB Opaque Algorithm: Type: 0x%02x, Length: %d", subtype, sublen);
1676 static void
1677 dissect_isis_lsp_clv_mt_cap_spbm_service_identifier(tvbuff_t *tvb,
1678 proto_tree *tree, int offset, int subtype, int sublen)
1680 const int BMAC_LEN = 6; /* B-MAC Address */
1681 const int BVID_LEN = 2; /* Base-VID */
1683 const int BMAC_OFFSET = 0;
1684 const int BVID_OFFSET = BMAC_OFFSET + BMAC_LEN;
1685 const int FIXED_LEN = BVID_OFFSET + BVID_LEN;
1687 const int ISID_LEN = 4;
1689 if (sublen < FIXED_LEN) {
1690 isis_dissect_unknown( tvb, tree, offset,
1691 "Short SPBM Service Identifier and Unicast Address subTLV (%d vs %d)", sublen, FIXED_LEN);
1692 return;
1694 else {
1695 proto_tree *subtree, *ti;
1696 int subofs = offset;
1697 const guint8 *bmac = tvb_get_ptr (tvb, subofs + BMAC_OFFSET, BMAC_LEN);
1698 const guint16 bvid = tvb_get_ntohs(tvb, subofs + BVID_OFFSET);
1700 /*************************/
1701 ti = proto_tree_add_text( tree, tvb, offset-2, sublen+2,
1702 "SPB Service ID and Unicast Address: Type: 0x%02x, Length: %d", subtype, sublen);
1703 subtree = proto_item_add_subtree(ti, ett_isis_lsp_clv_mt_cap_spbm_service_identifier);
1705 /*************************/
1706 proto_tree_add_text( subtree, tvb, subofs + BMAC_OFFSET, BMAC_LEN,
1707 "B-MAC: %02x-%02x-%02x-%02x-%02x-%02x",
1708 bmac[0],
1709 bmac[1],
1710 bmac[2],
1711 bmac[3],
1712 bmac[4],
1713 bmac[5]);
1714 proto_tree_add_text( subtree, tvb, subofs + BVID_OFFSET, BVID_LEN,
1715 "Base-VID: 0x%03x (%u)",
1716 bvid, bvid);
1718 subofs += FIXED_LEN;
1719 sublen -= FIXED_LEN;
1721 /*************************/
1722 while (sublen > 0) {
1723 if (sublen < ISID_LEN) {
1724 isis_dissect_unknown( tvb, subtree, offset,
1725 "Short ISID entry (%d vs %d)", sublen, ISID_LEN);
1726 return;
1728 else {
1729 const guint32 isid = tvb_get_ntohl(tvb, subofs);
1730 proto_tree_add_text( subtree, tvb, subofs, ISID_LEN,
1731 " T: %u, R: %u, ISID: 0x%06x (%d)",
1732 (isid >> 31) & 1,
1733 (isid >> 30) & 1,
1734 isid & 0x00ffffff,
1735 isid & 0x00ffffff);
1736 subofs += ISID_LEN;
1737 sublen -= ISID_LEN;
1742 static void
1743 dissect_isis_lsp_clv_mt_cap_spbv_mac_address(tvbuff_t *tvb,
1744 proto_tree *tree, int offset, int subtype, int sublen)
1746 guint16 fixed_data;
1747 guint16 spvid;
1748 guint8 sr_bit;
1749 const int GMAC_LEN = 6; /* GMAC Address */
1750 const int SPVID_LEN = 2; /* SPVID */
1751 const int MAC_TUPLE_LEN = 7;
1753 const int SPVID_OFFSET = 0;
1754 const int FIXED_LEN = SPVID_OFFSET + SPVID_LEN;
1756 if (sublen < FIXED_LEN) {
1757 isis_dissect_unknown( tvb, tree, offset,
1758 "Short SPBV Mac Address subTLV (%d vs %d)", sublen, FIXED_LEN);
1759 return;
1761 else {
1762 proto_tree *subtree, *ti;
1763 int subofs = offset;
1764 fixed_data = tvb_get_ntohs(tvb, subofs);
1765 spvid = (fixed_data & 0x0FFF);
1766 sr_bit = (fixed_data & 0x3000) >> 12;
1768 /*************************/
1769 ti = proto_tree_add_text( tree, tvb, offset-2, sublen+2,
1770 "SPBV Mac Address: Type: 0x%02x, Length: %d", subtype, sublen);
1771 subtree = proto_item_add_subtree(ti, ett_isis_lsp_clv_mt_cap_spbv_mac_address);
1773 /*************************/
1774 proto_tree_add_uint(subtree, hf_isis_lsp_spb_sr_bit,
1775 tvb, subofs, 1, sr_bit);
1776 proto_tree_add_uint(subtree, hf_isis_lsp_spb_spvid,
1777 tvb, subofs, 2, spvid);
1779 subofs += FIXED_LEN;
1780 sublen -= FIXED_LEN;
1782 /*************************/
1783 while (sublen > 0) {
1784 if (sublen < MAC_TUPLE_LEN) {
1785 isis_dissect_unknown( tvb, subtree, offset,
1786 " Short MAC Address entry (%d vs %d)", sublen, MAC_TUPLE_LEN);
1787 return;
1789 else {
1790 const guint32 tr_bit = tvb_get_guint8(tvb, subofs);
1791 const guint8 *gmac = tvb_get_ptr(tvb, subofs + 1, GMAC_LEN);
1792 proto_tree_add_text( subtree, tvb, subofs, MAC_TUPLE_LEN,
1793 " T: %u, R: %u, MAC: %02x-%02x-%02x-%02x-%02x-%02x",
1794 (tr_bit >> 7) & 1,
1795 (tr_bit >> 6) & 1,
1796 gmac[0],
1797 gmac[1],
1798 gmac[2],
1799 gmac[3],
1800 gmac[4],
1801 gmac[5]);
1802 subofs += MAC_TUPLE_LEN;
1803 sublen -= MAC_TUPLE_LEN;
1809 * Name: dissect_lsp_clv_mt_cap()
1811 * Description: Decode an ISIS MT-CAP CLV - code 144.
1813 * Input:
1814 * tvbuff_t * : tvbuffer for packet data
1815 * proto_tree * : proto tree to build on (may be null)
1816 * int : current offset into packet data
1817 * int : length of IDs in packet.
1818 * int : length of this clv
1820 * Output:
1821 * void, will modify proto_tree if not null.
1823 static void
1824 dissect_isis_lsp_clv_mt_cap(tvbuff_t *tvb, proto_tree *tree, int offset,
1825 int id_length _U_, int length)
1827 if (length >= 2) {
1828 /* mtid */
1829 guint16 mtid = tvb_get_ntohs(tvb, offset);
1830 proto_tree_add_text( tree, tvb, offset, 2,
1831 "MTID: 0x%03x, Overload: %d",
1832 (mtid & 0xfff),
1833 (mtid & 0x8000) ? 1 : 0);
1834 length -= 2;
1835 offset += 2;
1836 while (length >= 2) {
1837 guint8 subtype = tvb_get_guint8(tvb, offset);
1838 guint8 subtlvlen = tvb_get_guint8(tvb, offset+1);
1839 length -= 2;
1840 offset += 2;
1841 if (subtlvlen > length) {
1842 isis_dissect_unknown( tvb, tree, offset,
1843 "Short type 0x%02x TLV (%d vs %d)", subtype, subtlvlen, length);
1844 return;
1846 if (subtype == 0x01) { /* SPB Instance */
1847 dissect_isis_lsp_clv_mt_cap_spb_instance(tvb, tree, offset, subtype, subtlvlen);
1849 else if (subtype == 0x02) { /* OALG */
1850 dissect_isis_lsp_clv_mt_cap_spb_oalg(tvb, tree, offset, subtype, subtlvlen);
1852 else if (subtype == 0x03) { /* SPBM Service Identifier */
1853 dissect_isis_lsp_clv_mt_cap_spbm_service_identifier(tvb, tree, offset, subtype, subtlvlen);
1855 else if (subtype == 0x04) { /* SPBV Mac Address */
1856 dissect_isis_lsp_clv_mt_cap_spbv_mac_address(tvb, tree, offset, subtype, subtlvlen);
1858 else {
1859 isis_dissect_unknown( tvb, tree, offset,
1860 "Unknown SubTlv: Type: 0x%02x, Length: %d", subtype, subtlvlen);
1862 length -= subtlvlen;
1863 offset += subtlvlen;
1870 * Name: dissect_lsp_authentication_clv()
1872 * Description:
1873 * Decode for a lsp packets authenticaion clv. Calls into the
1874 * clv common one.
1876 * Input:
1877 * tvbuff_t * : tvbuffer for packet data
1878 * proto_tree * : proto tree to build on (may be null)
1879 * int : current offset into packet data
1880 * int : length of IDs in packet.
1881 * int : length of this clv
1883 * Output:
1884 * void, will modify proto_tree if not null.
1886 static void
1887 dissect_lsp_authentication_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1888 int id_length _U_, int length)
1890 isis_dissect_authentication_clv(tvb, tree, offset, length);
1894 * Name: dissect_lsp_ip_authentication_clv()
1896 * Description:
1897 * Decode for a lsp packets authenticaion clv. Calls into the
1898 * clv common one.
1900 * Input:
1901 * tvbuff_t * : tvbuffer for packet data
1902 * proto_tree * : proto tree to build on (may be null)
1903 * int : current offset into packet data
1904 * int : length of IDs in packet.
1905 * int : length of this clv
1907 * Output:
1908 * void, will modify proto_tree if not null.
1910 static void
1911 dissect_lsp_ip_authentication_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1912 int id_length _U_, int length)
1914 isis_dissect_ip_authentication_clv(tvb, tree, offset, length);
1918 * Name: dissect_lsp_area_address_clv()
1920 * Description:
1921 * Decode for a lsp packet's area address clv. Call into clv common
1922 * one.
1924 * Input:
1925 * tvbuff_t * : tvbuffer for packet data
1926 * proto_tree * : protocol display tree to fill out. May be NULL
1927 * int : offset into packet data where we are.
1928 * int : length of IDs in packet.
1929 * int : length of clv we are decoding
1931 * Output:
1932 * void, but we will add to proto tree if !NULL.
1934 static void
1935 dissect_lsp_area_address_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
1936 int id_length _U_, int length)
1938 isis_dissect_area_address_clv(tvb, tree, offset, length);
1942 * Name: dissect_lsp_eis_neighbors_clv_inner()
1944 * Description:
1945 * Real work horse for showing neighbors. This means we decode the
1946 * first octet as either virtual/!virtual (if show_virtual param is
1947 * set), or as a must == 0 reserved value.
1949 * Once past that, we decode n neighbor elements. Each neighbor
1950 * is comprised of a metric block (is dissect_metric) and the
1951 * addresses.
1953 * Input:
1954 * tvbuff_t * : tvbuffer for packet data
1955 * proto_tree * : protocol display tree to fill out. May be NULL
1956 * int : offset into packet data where we are.
1957 * int : length of IDs in packet.
1958 * int : length of clv we are decoding
1959 * int : set to decode first octet as virtual vs reserved == 0
1960 * int : set to indicate EIS instead of IS (6 octet per addr instead of 7)
1962 * Output:
1963 * void, but we will add to proto tree if !NULL.
1965 static void
1966 dissect_lsp_eis_neighbors_clv_inner(tvbuff_t *tvb, proto_tree *tree,
1967 int offset, int length, int id_length, int show_virtual, int is_eis)
1969 proto_item *ti;
1970 proto_tree *ntree = NULL;
1971 int tlen;
1973 if (!is_eis) {
1974 id_length++; /* IDs are one octet longer in IS neighbours */
1975 if ( tree ) {
1976 if ( show_virtual ) {
1977 /* virtual path flag */
1978 proto_tree_add_text ( tree, tvb, offset, 1,
1979 tvb_get_guint8(tvb, offset) ? "IsVirtual" : "IsNotVirtual" );
1980 } else {
1981 proto_tree_add_text ( tree, tvb, offset, 1,
1982 "Reserved value 0x%02x, must == 0",
1983 tvb_get_guint8(tvb, offset) );
1986 offset++;
1987 length--;
1989 tlen = 4 + id_length;
1991 while ( length > 0 ) {
1992 if (length<tlen) {
1993 isis_dissect_unknown(tvb, tree, offset,
1994 "short E/IS reachability (%d vs %d)", length,
1995 tlen );
1996 return;
1999 * Gotta build a sub-tree for all our pieces
2001 if ( tree ) {
2002 if ( is_eis ) {
2003 ti = proto_tree_add_text(tree, tvb, offset, tlen,
2004 "ES Neighbor: %s",
2005 print_system_id( tvb_get_ptr(tvb, offset+4, id_length), id_length ) );
2006 } else {
2007 ti = proto_tree_add_text(tree, tvb, offset, tlen,
2008 "IS Neighbor: %s",
2009 print_system_id(tvb_get_ptr(tvb, offset+4, id_length), id_length ) );
2011 ntree = proto_item_add_subtree(ti,
2012 ett_isis_lsp_clv_is_neighbors);
2016 proto_tree_add_text (ntree, tvb, offset, 1,
2017 "Default Metric: %d, %s",
2018 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset)),
2019 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset)) ? "External" : "Internal");
2021 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+1))) {
2022 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: Not supported");
2023 } else {
2024 proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric: %d, %s",
2025 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+1)),
2026 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+1)) ? "External" : "Internal");
2030 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+2))) {
2031 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: Not supported");
2032 } else {
2033 proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: %d, %s",
2034 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+2)),
2035 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+2)) ? "External" : "Internal");
2038 if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+3))) {
2039 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: Not supported");
2040 } else {
2041 proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric: %d, %s",
2042 ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+3)),
2043 ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+3)) ? "External" : "Internal");
2047 offset += tlen;
2048 length -= tlen;
2053 * Name: dissect_lsp_l1_is_neighbors_clv()
2055 * Description:
2056 * Dispatch a l1 intermediate system neighbor by calling
2057 * the inner function with show virtual set to TRUE and is es set to FALSE.
2059 * Input:
2060 * tvbuff_t * : tvbuffer for packet data
2061 * proto_tree * : protocol display tree to fill out. May be NULL
2062 * int : offset into packet data where we are.
2063 * int : length of IDs in packet.
2064 * int : length of clv we are decoding
2066 * Output:
2067 * void, but we will add to proto tree if !NULL.
2069 static void
2070 dissect_lsp_l1_is_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
2071 int id_length, int length)
2073 dissect_lsp_eis_neighbors_clv_inner(tvb, tree, offset,
2074 length, id_length, TRUE, FALSE);
2078 * Name: dissect_lsp_l1_es_neighbors_clv()
2080 * Description:
2081 * Dispatch a l1 end or intermediate system neighbor by calling
2082 * the inner function with show virtual set to TRUE and es set to TRUE.
2084 * Input:
2085 * tvbuff_t * : tvbuffer for packet data
2086 * proto_tree * : protocol display tree to fill out. May be NULL
2087 * int : offset into packet data where we are.
2088 * int : length of IDs in packet.
2089 * int : length of clv we are decoding
2091 * Output:
2092 * void, but we will add to proto tree if !NULL.
2094 static void
2095 dissect_lsp_l1_es_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
2096 int id_length, int length)
2098 dissect_lsp_eis_neighbors_clv_inner(tvb, tree, offset,
2099 length, id_length, TRUE, TRUE);
2103 * Name: dissect_lsp_l2_is_neighbors_clv()
2105 * Description:
2106 * Dispatch a l2 intermediate system neighbor by calling
2107 * the inner function with show virtual set to FALSE, and is es set
2108 * to FALSE
2110 * Input:
2111 * tvbuff_t * : tvbuffer for packet data
2112 * proto_tree * : protocol display tree to fill out. May be NULL
2113 * int : offset into packet data where we are.
2114 * int : length of IDs in packet.
2115 * int : length of clv we are decoding
2117 * Output:
2118 * void, but we will add to proto tree if !NULL.
2120 static void
2121 dissect_lsp_l2_is_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
2122 int id_length, int length)
2124 dissect_lsp_eis_neighbors_clv_inner(tvb, tree, offset,
2125 length, id_length, FALSE, FALSE);
2130 * Name: dissect_subclv_admin_group ()
2132 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
2134 * This function is called by dissect_lsp_ext_is_reachability_clv()
2135 * for dissect the administrive group sub-CLV (code 3).
2137 * Input:
2138 * tvbuff_t * : tvbuffer for packet data
2139 * proto_tree * : protocol display tree to fill out.
2140 * int : offset into packet data where we are (beginning of the sub_clv value).
2142 * Output:
2143 * void
2145 static void
2146 dissect_subclv_admin_group (tvbuff_t *tvb, proto_tree *tree, int offset) {
2147 proto_item *ti;
2148 proto_tree *ntree;
2149 guint32 clv_value;
2150 guint32 mask;
2151 int i;
2153 ti = proto_tree_add_text(tree, tvb, offset-2, 6, "Administrative group(s):");
2154 ntree = proto_item_add_subtree (ti, ett_isis_lsp_subclv_admin_group);
2156 clv_value = tvb_get_ntohl(tvb, offset);
2157 mask = 1;
2158 for (i = 0 ; i < 32 ; i++) {
2159 if ( (clv_value & mask) != 0 ) {
2160 proto_tree_add_text (ntree, tvb, offset, 4, "group %d", i);
2162 mask <<= 1;
2167 * Name: dissect_subclv_max_bw ()
2169 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
2171 * This function is called by dissect_lsp_ext_is_reachability_clv()
2172 * for dissect the maximum link bandwidth sub-CLV (code 9).
2174 * Input:
2175 * tvbuff_t * : tvbuffer for packet data
2176 * proto_tree * : protocol display tree to fill out.
2177 * int : offset into packet data where we are (beginning of the sub_clv value).
2179 * Output:
2180 * void
2182 static void
2183 dissect_subclv_max_bw(tvbuff_t *tvb, proto_tree *tree, int offset)
2185 gfloat bw;
2187 bw = tvb_get_ntohieee_float(tvb, offset);
2188 proto_tree_add_text (tree, tvb, offset-2, 6,
2189 "Maximum link bandwidth : %.2f Mbps", bw*8/1000000 );
2193 * Name: dissect_subclv_rsv_bw ()
2195 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
2197 * This function is called by dissect_lsp_ext_is_reachability_clv()
2198 * for dissect the reservable link bandwidth sub-CLV (code 10).
2200 * Input:
2201 * tvbuff_t * : tvbuffer for packet data
2202 * proto_tree * : protocol display tree to fill out.
2203 * int : offset into packet data where we are (beginning of the sub_clv value).
2205 * Output:
2206 * void
2208 static void
2209 dissect_subclv_rsv_bw(tvbuff_t *tvb, proto_tree *tree, int offset)
2211 gfloat bw;
2213 bw = tvb_get_ntohieee_float(tvb, offset);
2214 proto_tree_add_text (tree, tvb, offset-2, 6,
2215 "Reservable link bandwidth: %.2f Mbps", bw*8/1000000 );
2219 * Name: dissect_subclv_unrsv_bw ()
2221 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
2223 * This function is called by dissect_lsp_ext_is_reachability_clv()
2224 * for dissect the unreserved bandwidth sub-CLV (code 11).
2226 * Input:
2227 * tvbuff_t * : tvbuffer for packet data
2228 * proto_tree * : protocol display tree to fill out.
2229 * int : offset into packet data where we are (beginning of the sub_clv value).
2231 * Output:
2232 * void
2234 static void
2235 dissect_subclv_unrsv_bw(tvbuff_t *tvb, proto_tree *tree, int offset)
2237 proto_item *ti;
2238 proto_tree *ntree;
2239 gfloat bw;
2240 int i;
2242 ti = proto_tree_add_text (tree, tvb, offset-2, 34, "Unreserved bandwidth:");
2243 ntree = proto_item_add_subtree (ti, ett_isis_lsp_subclv_unrsv_bw);
2245 for (i = 0 ; i < 8 ; i++) {
2246 bw = tvb_get_ntohieee_float(tvb, offset+4*i);
2247 proto_tree_add_text (ntree, tvb, offset+4*i, 4,
2248 "priority level %d: %.2f Mbps", i, bw*8/1000000 );
2253 * Name: dissect_subclv_spb_link_metric ()
2255 * Description: Called by function dissect_lsp_ext_is_reachability_clv().
2257 * This function is called by dissect_lsp_ext_is_reachability_clv()
2258 * for dissect the SPB link metric sub-CLV (code 29).
2260 * Input:
2261 * tvbuff_t * : tvbuffer for packet data
2262 * proto_tree * : protocol display tree to fill out.
2263 * int : offset into packet data where we are (beginning of the sub_clv value).
2264 * int : subtlv type
2265 * int : subtlv length
2267 * Output:
2268 * void
2271 static void
2272 dissect_subclv_spb_link_metric(tvbuff_t *tvb,
2273 proto_tree *tree, int offset, int subtype, int sublen)
2275 const int SUBLEN = 6;
2277 if (sublen != SUBLEN) {
2278 isis_dissect_unknown( tvb, tree, offset,
2279 "Short SPB Link Metric sub-TLV (%d vs %d)", sublen, SUBLEN);
2280 return;
2282 else {
2283 proto_tree *subtree, *ti;
2284 ti = proto_tree_add_text( tree, tvb, offset-2, sublen+2,
2285 "SPB Link Metric: Type: 0x%02x (%d), Length: %d", subtype, subtype, sublen);
2286 subtree = proto_item_add_subtree(ti, ett_isis_lsp_subclv_spb_link_metric);
2288 proto_tree_add_item(subtree, hf_isis_lsp_spb_link_metric,
2289 tvb, offset, 3, ENC_BIG_ENDIAN);
2291 proto_tree_add_item(subtree, hf_isis_lsp_spb_port_count,
2292 tvb, offset+3, 1, ENC_BIG_ENDIAN);
2294 proto_tree_add_item(subtree, hf_isis_lsp_spb_port_id,
2295 tvb, offset+4, 2, ENC_BIG_ENDIAN);
2300 * Name: dissect_lsp_ext_is_reachability_clv()
2302 * Description: Decode a Extended IS Reachability CLV - code 22
2304 * The extended IS reachability TLV is an extended version
2305 * of the IS reachability TLV (code 2). It encodes the metric
2306 * as a 24-bit unsigned interger and allows to add sub-CLV(s).
2308 * CALLED BY TLV 222 DISSECTOR
2310 * Input:
2311 * tvbuff_t * : tvbuffer for packet data
2312 * proto_tree * : protocol display tree to fill out. May be NULL
2313 * int : offset into packet data where we are.
2314 * int : length of IDs in packet.
2315 * int : length of clv we are decoding
2317 * Output:
2318 * void, but we will add to proto tree if !NULL.
2320 static void
2321 dissect_lsp_ext_is_reachability_clv(tvbuff_t *tvb, proto_tree *tree,
2322 int offset, int id_length _U_, int length)
2324 proto_item *ti;
2325 proto_tree *ntree = NULL;
2326 guint subclvs_len;
2327 guint len, i;
2328 guint clv_code, clv_len;
2330 if (!tree) return;
2332 while (length > 0) {
2333 ti = proto_tree_add_text (tree, tvb, offset, -1,
2334 "IS neighbor: %s",
2335 print_system_id (tvb_get_ptr(tvb, offset, 7), 7) );
2336 ntree = proto_item_add_subtree (ti,
2337 ett_isis_lsp_part_of_clv_ext_is_reachability );
2339 proto_tree_add_text (ntree, tvb, offset+7, 3,
2340 "Metric: %d", tvb_get_ntoh24(tvb, offset+7) );
2342 subclvs_len = tvb_get_guint8(tvb, offset+10);
2343 if (subclvs_len == 0) {
2344 proto_tree_add_text (ntree, tvb, offset+10, 1, "no sub-TLVs present");
2346 else {
2347 i = 0;
2348 while (i < subclvs_len) {
2349 clv_code = tvb_get_guint8(tvb, offset+11+i);
2350 clv_len = tvb_get_guint8(tvb, offset+12+i);
2351 switch (clv_code) {
2352 case 3 :
2353 dissect_subclv_admin_group(tvb, ntree, offset+13+i);
2354 break;
2355 case 4 :
2356 proto_tree_add_text(ntree, tvb, offset+13+i, 4,
2357 "Link Local Identifier: %d", tvb_get_ntohl(tvb, offset+13+i));
2358 proto_tree_add_text(ntree, tvb, offset+17+i, 4,
2359 "Link Remote Identifier: %d", tvb_get_ntohl(tvb, offset+17+i));
2360 break;
2361 case 6 :
2362 proto_tree_add_text (ntree, tvb, offset+11+i, 6,
2363 "IPv4 interface address: %s", tvb_ip_to_str(tvb, offset+13+i));
2364 break;
2365 case 8 :
2366 proto_tree_add_text (ntree, tvb, offset+11+i, 6,
2367 "IPv4 neighbor address: %s", tvb_ip_to_str(tvb, offset+13+i));
2368 break;
2369 case 9 :
2370 dissect_subclv_max_bw (tvb, ntree, offset+13+i);
2371 break;
2372 case 10:
2373 dissect_subclv_rsv_bw (tvb, ntree, offset+13+i);
2374 break;
2375 case 11:
2376 dissect_subclv_unrsv_bw (tvb, ntree, offset+13+i);
2377 break;
2378 case 18:
2379 proto_tree_add_text (ntree, tvb, offset+11+i, 5,
2380 "Traffic engineering default metric: %d",
2381 tvb_get_ntoh24(tvb, offset+13+i) );
2382 break;
2383 case 29:
2384 dissect_subclv_spb_link_metric(tvb, ntree,
2385 offset+13+i, clv_code, clv_len);
2386 break;
2387 case 250:
2388 case 251:
2389 case 252:
2390 case 253:
2391 case 254:
2392 proto_tree_add_text (ntree, tvb, offset+11+i, clv_len+2,
2393 "Unknown Cisco specific extensions: code %d, length %d",
2394 clv_code, clv_len );
2395 break;
2396 default :
2397 proto_tree_add_text (ntree, tvb, offset+11+i, clv_len+2,
2398 "Unknown sub-CLV: code %d, length %d", clv_code, clv_len );
2399 break;
2401 i += clv_len + 2;
2405 len = 11 + subclvs_len;
2406 proto_item_set_len (ti, len);
2407 offset += len;
2408 length -= len;
2413 * Name: dissect_lsp_mt_reachable_IPv4_prefx_clv()
2415 * Description: Decode Multi-Topology IPv4 Prefixes - code 235
2418 * Input:
2419 * tvbuff_t * : tvbuffer for packet data
2420 * proto_tree * : protocol display tree to fill out. May be NULL
2421 * int : offset into packet data where we are.
2422 * int : length of IDs in packet.
2423 * int : length of clv we are decoding
2425 * Output:
2426 * void, but we will add to proto tree if !NULL.
2428 static void
2429 dissect_lsp_mt_reachable_IPv4_prefx_clv(tvbuff_t *tvb,
2430 proto_tree *tree, int offset, int id_length _U_, int length)
2432 if (!tree) return;
2433 if (length < 2) {
2434 isis_dissect_unknown(tvb, tree, offset,
2435 "short lsp multi-topology reachable IPv4 prefixes(%d vs %d)", length,
2436 2 );
2437 return;
2439 dissect_lsp_mt_id(tvb, tree, offset);
2440 dissect_lsp_ext_ip_reachability_clv(tvb, tree, offset+2, 0, length-2);
2444 * Name: dissect_lsp_mt_reachable_IPv6_prefx_clv()
2446 * Description: Decode Multi-Topology IPv6 Prefixes - code 237
2449 * Input:
2450 * tvbuff_t * : tvbuffer for packet data
2451 * proto_tree * : protocol display tree to fill out. May be NULL
2452 * int : offset into packet data where we are.
2453 * int : length of IDs in packet.
2454 * int : length of clv we are decoding
2456 * Output:
2457 * void, but we will add to proto tree if !NULL.
2459 static void
2460 dissect_lsp_mt_reachable_IPv6_prefx_clv(tvbuff_t *tvb,
2461 proto_tree *tree, int offset, int id_length _U_, int length)
2463 if (!tree) return;
2464 if (length < 2) {
2465 isis_dissect_unknown(tvb, tree, offset,
2466 "short lsp multi-topology reachable IPv6 prefixes(%d vs %d)", length,
2467 2 );
2468 return;
2470 dissect_lsp_mt_id(tvb, tree, offset);
2471 dissect_lsp_ipv6_reachability_clv(tvb, tree, offset+2, 0, length-2);
2476 * Name: dissect_lsp_mt_is_reachability_clv()
2478 * Description: Decode Multi-Topology Intermediate Systems - code 222
2481 * Input:
2482 * tvbuff_t * : tvbuffer for packet data
2483 * proto_tree * : protocol display tree to fill out. May be NULL
2484 * int : offset into packet data where we are.
2485 * int : unused
2486 * int : length of clv we are decoding
2488 * Output:
2489 * void, but we will add to proto tree if !NULL.
2492 static void
2493 dissect_lsp_mt_is_reachability_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
2494 int id_length _U_, int length)
2496 if (!tree) return;
2497 if (length < 2) {
2498 isis_dissect_unknown(tvb, tree, offset,
2499 "short lsp reachability(%d vs %d)", length,
2500 2 );
2501 return;
2505 * the MT ID value dissection is used in other LSPs so we push it
2506 * in a function
2508 dissect_lsp_mt_id(tvb, tree, offset);
2510 * fix here. No need to parse TLV 22 (with bugs) while it is
2511 * already done correctly!!
2513 dissect_lsp_ext_is_reachability_clv(tvb, tree, offset+2, 0, length-2);
2517 * Name: dissect_lsp_partition_dis_clv()
2519 * Description:
2520 * This CLV is used to indicate which system is the designated
2521 * IS for partition repair. This means just putting out the
2522 * "id_length"-octet IS.
2524 * Input:
2525 * tvbuff_t * : tvbuffer for packet data
2526 * proto_tree * : protocol display tree to fill out. May be NULL
2527 * int : offset into packet data where we are.
2528 * int : length of IDs in packet.
2529 * int : length of clv we are decoding
2531 * Output:
2532 * void, but we will add to proto tree if !NULL.
2534 static void
2535 dissect_lsp_partition_dis_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
2536 int id_length, int length)
2538 if ( length < id_length ) {
2539 isis_dissect_unknown(tvb, tree, offset,
2540 "short lsp partition DIS(%d vs %d)", length,
2541 id_length );
2542 return;
2545 * Gotta build a sub-tree for all our pieces
2547 if ( tree ) {
2548 proto_tree_add_text ( tree, tvb, offset, id_length,
2549 "Partition designated L2 IS: %s",
2550 print_system_id( tvb_get_ptr(tvb, offset, id_length), id_length ) );
2552 length -= id_length;
2553 offset += id_length;
2554 if ( length > 0 ) {
2555 isis_dissect_unknown(tvb, tree, offset,
2556 "Long lsp partition DIS, %d left over", length );
2557 return;
2562 * Name: dissect_lsp_prefix_neighbors_clv()
2564 * Description:
2565 * The prefix CLV describes what other (OSI) networks we can reach
2566 * and what their cost is. It is built from a metric block
2567 * (see dissect_metric) followed by n addresses.
2569 * Input:
2570 * tvbuff_t * : tvbuffer for packet data
2571 * proto_tree * : protocol display tree to fill out. May be NULL
2572 * int : offset into packet data where we are.
2573 * int : length of IDs in packet.
2574 * int : length of clv we are decoding
2576 * Output:
2577 * void, but we will add to proto tree if !NULL.
2579 static void
2580 dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
2581 int id_length _U_, int length)
2583 char *sbuf;
2584 int mylen;
2586 if ( length < 4 ) {
2587 isis_dissect_unknown(tvb, tree, offset,
2588 "Short lsp prefix neighbors (%d vs 4)", length );
2589 return;
2591 if ( tree ) {
2592 dissect_metric (tvb, tree, offset,
2593 tvb_get_guint8(tvb, offset), "Default", TRUE );
2594 dissect_metric (tvb, tree, offset+1,
2595 tvb_get_guint8(tvb, offset+1), "Delay", FALSE );
2596 dissect_metric (tvb, tree, offset+2,
2597 tvb_get_guint8(tvb, offset+2), "Expense", FALSE );
2598 dissect_metric (tvb, tree, offset+3,
2599 tvb_get_guint8(tvb, offset+3), "Error", FALSE );
2601 offset += 4;
2602 length -= 4;
2603 while ( length > 0 ) {
2604 mylen = tvb_get_guint8(tvb, offset);
2605 length--;
2606 if (length<=0) {
2607 isis_dissect_unknown(tvb, tree, offset,
2608 "Zero payload space after length in prefix neighbor" );
2609 return;
2611 if ( mylen > length) {
2612 isis_dissect_unknown(tvb, tree, offset,
2613 "Integral length of prefix neighbor too long (%d vs %d)",
2614 mylen, length );
2615 return;
2619 * Lets turn the area address into "standard" 0000.0000.etc
2620 * format string.
2622 sbuf = print_area( tvb_get_ptr(tvb, offset+1, mylen), mylen );
2623 /* and spit it out */
2624 if ( tree ) {
2625 proto_tree_add_text ( tree, tvb, offset, mylen + 1,
2626 "Area address (%d): %s", mylen, sbuf );
2628 offset += mylen + 1;
2629 length -= mylen; /* length already adjusted for len fld*/
2633 static void isis_lsp_checkum_additional_info(tvbuff_t * tvb, packet_info * pinfo,
2634 proto_item * it_cksum, int offset, gboolean is_cksum_correct)
2636 proto_tree * checksum_tree;
2637 proto_item * item;
2639 checksum_tree = proto_item_add_subtree(it_cksum, ett_isis_lsp_cksum);
2640 item = proto_tree_add_boolean(checksum_tree, hf_isis_lsp_checksum_good, tvb,
2641 offset, 2, is_cksum_correct);
2642 PROTO_ITEM_SET_GENERATED(item);
2643 item = proto_tree_add_boolean(checksum_tree, hf_isis_lsp_checksum_bad, tvb,
2644 offset, 2, !is_cksum_correct);
2645 PROTO_ITEM_SET_GENERATED(item);
2646 if (!is_cksum_correct) {
2647 expert_add_info(pinfo, item, &ie_isis_lsp_checksum_bad);
2648 col_append_str(pinfo->cinfo, COL_INFO, " [ISIS CHECKSUM INCORRECT]");
2654 * Name: isis_dissect_isis_lsp()
2656 * Description:
2657 * Print out the LSP part of the main header and then call the CLV
2658 * de-mangler with the right list of valid CLVs.
2660 * Input:
2661 * tvbuff_t * : tvbuffer for packet data
2662 * proto_tree * : protocol display tree to add to. May be NULL.
2663 * int offset : our offset into packet data.
2664 * int : LSP type, a la packet-isis.h ISIS_TYPE_* values
2665 * int : header length of packet.
2666 * int : length of IDs in packet.
2668 * Output:
2669 * void, but we will add to proto tree if !NULL.
2671 void
2672 isis_dissect_isis_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2673 int lsp_type, int header_length, int id_length)
2675 proto_item *ti, *to, *ta;
2676 proto_tree *lsp_tree = NULL, *info_tree, *att_tree;
2677 guint16 pdu_length, lifetime, checksum, cacl_checksum=0;
2678 guint8 lsp_info, lsp_att;
2679 int len, offset_checksum;
2680 proto_item *it_cksum;
2682 if (tree) {
2683 ti = proto_tree_add_text(tree, tvb, offset, -1,
2684 PROTO_STRING_LSP);
2685 lsp_tree = proto_item_add_subtree(ti, ett_isis_lsp);
2688 pdu_length = tvb_get_ntohs(tvb, offset);
2689 if (tree) {
2690 proto_tree_add_uint(lsp_tree, hf_isis_lsp_pdu_length, tvb,
2691 offset, 2, pdu_length);
2693 offset += 2;
2695 if (tree) {
2696 proto_tree_add_item(lsp_tree, hf_isis_lsp_remaining_life,
2697 tvb, offset, 2, ENC_BIG_ENDIAN);
2699 lifetime = tvb_get_ntohs(tvb, offset);
2700 offset += 2;
2701 offset_checksum = offset;
2703 if (tree) {
2704 char* value = print_system_id( tvb_get_ptr(tvb, offset, id_length+2),
2705 id_length+2);
2706 proto_tree_add_string_format_value(lsp_tree, hf_isis_lsp_lsp_id,
2707 tvb, offset, id_length + 2,
2708 value, "%s", value);
2711 col_append_fstr(pinfo->cinfo, COL_INFO, ", LSP-ID: %s",
2712 print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) );
2714 offset += id_length + 2;
2716 proto_tree_add_item(lsp_tree, hf_isis_lsp_sequence_number,
2717 tvb, offset, 4, ENC_BIG_ENDIAN);
2719 col_append_fstr(pinfo->cinfo, COL_INFO, ", Sequence: 0x%08x, Lifetime: %5us",
2720 tvb_get_ntohl(tvb, offset),
2721 tvb_get_ntohs(tvb, offset - (id_length+2+2)));
2723 offset += 4;
2725 if (tree) {
2726 checksum = lifetime ? tvb_get_ntohs(tvb, offset) : 0;
2727 switch (check_and_get_checksum(tvb, offset_checksum, pdu_length-12, checksum, offset, &cacl_checksum)) {
2728 case NO_CKSUM :
2729 checksum = tvb_get_ntohs(tvb, offset);
2730 proto_tree_add_uint_format_value(lsp_tree, hf_isis_lsp_checksum, tvb, offset, 2, checksum,
2731 "0x%04x [unused]", checksum);
2732 break;
2733 case DATA_MISSING :
2734 isis_dissect_unknown(tvb, tree, offset,
2735 "[packet length %d went beyond packet]",
2736 tvb_length_remaining(tvb, offset_checksum));
2737 break;
2738 case CKSUM_NOT_OK :
2739 it_cksum = proto_tree_add_uint_format_value(lsp_tree, hf_isis_lsp_checksum, tvb, offset, 2, checksum,
2740 "0x%04x [incorrect, should be 0x%04x]",
2741 checksum, cacl_checksum);
2742 isis_lsp_checkum_additional_info(tvb, pinfo, it_cksum, offset, FALSE);
2743 break;
2744 case CKSUM_OK :
2745 it_cksum = proto_tree_add_uint_format_value(lsp_tree, hf_isis_lsp_checksum, tvb, offset, 2, checksum,
2746 "0x%04x [correct]", checksum);
2747 isis_lsp_checkum_additional_info(tvb, pinfo, it_cksum, offset, TRUE);
2748 break;
2749 default :
2750 g_message("'check_and_get_checksum' returned an invalid value");
2753 offset += 2;
2755 if (tree) {
2757 * P | ATT | HIPPITY | IS TYPE description.
2759 lsp_info = tvb_get_guint8(tvb, offset);
2760 to = proto_tree_add_text(lsp_tree, tvb, offset, 1,
2761 "Type block(0x%02x): Partition Repair:%d, Attached bits:%d, Overload bit:%d, IS type:%d",
2762 lsp_info,
2763 ISIS_LSP_PARTITION(lsp_info),
2764 ISIS_LSP_ATT(lsp_info),
2765 ISIS_LSP_HIPPITY(lsp_info),
2766 ISIS_LSP_IS_TYPE(lsp_info)
2769 info_tree = proto_item_add_subtree(to, ett_isis_lsp_info);
2770 proto_tree_add_boolean(info_tree, hf_isis_lsp_p, tvb, offset, 1, lsp_info);
2771 ta = proto_tree_add_uint(info_tree, hf_isis_lsp_att, tvb, offset, 1, lsp_info);
2772 att_tree = proto_item_add_subtree(ta, ett_isis_lsp_att);
2773 lsp_att = ISIS_LSP_ATT(lsp_info);
2774 proto_tree_add_text(att_tree, tvb, offset, 1,
2775 "%d... = Error metric: %s", ISIS_LSP_ATT_ERROR(lsp_att), ISIS_LSP_ATT_ERROR(lsp_att) ? "Set" : "Unset");
2776 proto_tree_add_text(att_tree, tvb, offset, 1,
2777 ".%d.. = Expense metric: %s", ISIS_LSP_ATT_EXPENSE(lsp_att), ISIS_LSP_ATT_EXPENSE(lsp_att) ? "Set" : "Unset");
2778 proto_tree_add_text(att_tree, tvb, offset, 1,
2779 "..%d. = Delay metric: %s", ISIS_LSP_ATT_DELAY(lsp_att), ISIS_LSP_ATT_DELAY(lsp_att) ? "Set" : "Unset");
2780 proto_tree_add_text(att_tree, tvb, offset, 1,
2781 "...%d = Default metric: %s", ISIS_LSP_ATT_DEFAULT(lsp_att), ISIS_LSP_ATT_DEFAULT(lsp_att) ? "Set" : "Unset");
2782 proto_tree_add_boolean(info_tree, hf_isis_lsp_hippity, tvb, offset, 1, lsp_info);
2783 proto_tree_add_uint(info_tree, hf_isis_lsp_is_type, tvb, offset, 1, lsp_info);
2785 offset += 1;
2787 len = pdu_length - header_length;
2788 if (len < 0) {
2789 isis_dissect_unknown(tvb, tree, offset,
2790 "packet header length %d went beyond packet",
2791 header_length );
2792 return;
2795 * Now, we need to decode our CLVs. We need to pass in
2796 * our list of valid ones!
2798 if (lsp_type == ISIS_TYPE_L1_LSP) {
2799 isis_dissect_clvs(tvb, lsp_tree, offset,
2800 clv_l1_lsp_opts, len, id_length,
2801 ett_isis_lsp_clv_unknown );
2802 } else {
2803 isis_dissect_clvs(tvb, lsp_tree, offset,
2804 clv_l2_lsp_opts, len, id_length,
2805 ett_isis_lsp_clv_unknown );
2809 * Name: isis_register_lsp()
2811 * Description:
2812 * Register our protocol sub-sets with protocol manager.
2814 * Input:
2815 * int : protocol index for the ISIS protocol
2817 * Output:
2818 * void
2820 void
2821 isis_register_lsp(int proto_isis) {
2822 static hf_register_info hf[] = {
2823 { &hf_isis_lsp_pdu_length,
2824 { "PDU length", "isis.lsp.pdu_length", FT_UINT16,
2825 BASE_DEC, NULL, 0x0, NULL, HFILL }},
2827 { &hf_isis_lsp_remaining_life,
2828 { "Remaining lifetime", "isis.lsp.remaining_life", FT_UINT16,
2829 BASE_DEC, NULL, 0x0, NULL, HFILL }},
2831 { &hf_isis_lsp_lsp_id,
2832 { "LSP-ID", "isis.lsp.lsp_id", FT_STRING,
2833 BASE_NONE, NULL, 0x0, NULL, HFILL }},
2835 { &hf_isis_lsp_hostname,
2836 { "Hostname", "isis.lsp.hostname", FT_STRING,
2837 BASE_NONE, NULL, 0x0, NULL, HFILL }},
2839 { &hf_isis_lsp_sequence_number,
2840 { "Sequence number", "isis.lsp.sequence_number",
2841 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2843 { &hf_isis_lsp_checksum,
2844 { "Checksum", "isis.lsp.checksum",FT_UINT16,
2845 BASE_HEX, NULL, 0x0, NULL, HFILL }},
2847 { &hf_isis_lsp_checksum_good,
2848 { "Good Checksum", "isis.lsp.checksum_good", FT_BOOLEAN, BASE_NONE,
2849 NULL, 0x0, "Good IS-IS LSP Checksum", HFILL }},
2851 { &hf_isis_lsp_checksum_bad,
2852 { "Bad Checksum", "isis.lsp.checksum_bad", FT_BOOLEAN, BASE_NONE,
2853 NULL, 0x0, "Bad IS-IS LSP Checksum", HFILL }},
2855 { &hf_isis_lsp_clv_ipv4_int_addr,
2856 { "IPv4 interface address", "isis.lsp.clv_ipv4_int_addr", FT_IPv4,
2857 BASE_NONE, NULL, 0x0, NULL, HFILL }},
2859 { &hf_isis_lsp_clv_ipv6_int_addr,
2860 { "IPv6 interface address", "isis.lsp.clv_ipv6_int_addr", FT_IPv6,
2861 BASE_NONE, NULL, 0x0, NULL, HFILL }},
2863 { &hf_isis_lsp_clv_te_router_id,
2864 { "Traffic Engineering Router ID", "isis.lsp.clv_te_router_id", FT_IPv4,
2865 BASE_NONE, NULL, 0x0, NULL, HFILL }},
2867 { &hf_isis_lsp_clv_mt,
2868 { "MT-ID", "isis.lsp.clv_mt",
2869 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2871 { &hf_isis_lsp_p,
2872 { "Partition Repair", "isis.lsp.partition_repair", FT_BOOLEAN, 8,
2873 TFS(&tfs_supported_not_supported), ISIS_LSP_PARTITION_MASK,
2874 "If set, this router supports the optional Partition Repair function", HFILL }},
2876 { &hf_isis_lsp_att,
2877 { "Attachment", "isis.lsp.att", FT_UINT8, BASE_DEC,
2878 NULL, ISIS_LSP_ATT_MASK,
2879 NULL, HFILL }},
2881 { &hf_isis_lsp_hippity,
2882 { "Overload bit", "isis.lsp.overload", FT_BOOLEAN, 8,
2883 TFS(&tfs_set_notset), ISIS_LSP_HIPPITY_MASK,
2884 "If set, this router will not be used by any decision process to calculate routes", HFILL }},
2886 { &hf_isis_lsp_root_id,
2887 { "Root Bridge ID", "isis.lsp.root.id", FT_UINT64, BASE_HEX,
2888 NULL, 0x0, NULL, HFILL }},
2890 { &hf_isis_lsp_is_type,
2891 { "Type of Intermediate System", "isis.lsp.is_type", FT_UINT8, BASE_DEC,
2892 VALS(isis_lsp_istype_vals), ISIS_LSP_IS_TYPE_MASK,
2893 NULL, HFILL }},
2895 { &hf_isis_lsp_spb_link_metric,
2896 { "SPB Link Metric", "isis.lsp.spb.link_metric",
2897 FT_UINT24, BASE_HEX_DEC, NULL, 0, NULL, HFILL }},
2899 { &hf_isis_lsp_spb_port_count,
2900 { "Number of Ports", "isis.lsp.spb.port_count",
2901 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
2903 { &hf_isis_lsp_spb_port_id,
2904 { "Port Id", "isis.lsp.spb.port_id",
2905 FT_UINT16, BASE_HEX_DEC, NULL, 0, NULL, HFILL }},
2907 { &hf_isis_lsp_spb_sr_bit,
2908 { "SR Bit", "isis.lsp.spb.sr_bit",
2909 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
2911 { &hf_isis_lsp_spb_spvid,
2912 { "SPVID", "isis.lsp.spb.spvid",
2913 FT_UINT16, BASE_HEX_DEC, NULL, 0, NULL, HFILL }}
2916 static gint *ett[] = {
2917 &ett_isis_lsp,
2918 &ett_isis_lsp_info,
2919 &ett_isis_lsp_att,
2920 &ett_isis_lsp_cksum,
2921 &ett_isis_lsp_clv_area_addr,
2922 &ett_isis_lsp_clv_is_neighbors,
2923 &ett_isis_lsp_clv_ext_is_reachability, /* CLV 22 */
2924 &ett_isis_lsp_part_of_clv_ext_is_reachability,
2925 &ett_isis_lsp_subclv_admin_group,
2926 &ett_isis_lsp_subclv_unrsv_bw,
2927 &ett_isis_lsp_subclv_spb_link_metric,
2928 &ett_isis_lsp_clv_unknown,
2929 &ett_isis_lsp_clv_partition_dis,
2930 &ett_isis_lsp_clv_prefix_neighbors,
2931 &ett_isis_lsp_clv_authentication,
2932 &ett_isis_lsp_clv_ip_authentication,
2933 &ett_isis_lsp_clv_nlpid,
2934 &ett_isis_lsp_clv_hostname,
2935 &ett_isis_lsp_clv_ipv4_int_addr,
2936 &ett_isis_lsp_clv_ipv6_int_addr, /* CLV 232 */
2937 &ett_isis_lsp_clv_mt_cap,
2938 &ett_isis_lsp_clv_mt_cap_spb_instance,
2939 &ett_isis_lsp_clv_mt_cap_spbm_service_identifier,
2940 &ett_isis_lsp_clv_te_router_id,
2941 &ett_isis_lsp_clv_ip_reachability,
2942 &ett_isis_lsp_clv_ip_reach_subclv,
2943 &ett_isis_lsp_clv_ext_ip_reachability, /* CLV 135 */
2944 &ett_isis_lsp_part_of_clv_ext_ip_reachability,
2945 &ett_isis_lsp_clv_ipv6_reachability, /* CLV 236 */
2946 &ett_isis_lsp_part_of_clv_ipv6_reachability,
2947 &ett_isis_lsp_clv_mt,
2948 &ett_isis_lsp_clv_mt_is,
2949 &ett_isis_lsp_part_of_clv_mt_is,
2950 &ett_isis_lsp_clv_rt_capable_IPv4_prefx,
2951 &ett_isis_lsp_clv_grp_address_IPv4_prefx, /*CLV 142*/
2952 &ett_isis_lsp_clv_mt_reachable_IPv4_prefx,
2953 &ett_isis_lsp_clv_mt_reachable_IPv6_prefx,
2954 &ett_isis_lsp_clv_mt_cap_spbv_mac_address
2957 static ei_register_info ei[] = {
2958 { &ie_isis_lsp_checksum_bad, { "isis.lsp.checksum_bad.expert", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }},
2961 expert_module_t* expert_isis;
2963 proto_register_field_array(proto_isis, hf, array_length(hf));
2964 proto_register_subtree_array(ett, array_length(ett));
2965 expert_isis = expert_register_protocol(proto_isis);
2966 expert_register_field_array(expert_isis, ei, array_length(ei));