2 * Routines for decoding isis lsp packets and their CLVs
4 * $Id: packet-isis-lsp.c,v 1.10 2001/01/03 06:55:29 guy Exp $
5 * Stuart Stanley <stuarts@mxmail.net>
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@zing.org>
9 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
33 #ifdef HAVE_SYS_TYPES_H
34 # include <sys/types.h>
41 #ifdef HAVE_NET_INET_H
46 #include "packet-osi.h"
47 #include "packet-isis.h"
48 #include "packet-isis-clv.h"
49 #include "packet-isis-lsp.h"
53 static int proto_isis_lsp = -1;
54 static int hf_isis_lsp_pdu_length = -1;
55 static int hf_isis_lsp_remaining_life = -1;
56 static int hf_isis_lsp_sequence_number = -1;
57 static int hf_isis_lsp_checksum = -1;
58 static int hf_isis_lsp_clv_ipv4_int_addr = -1;
60 static gint ett_isis_lsp = -1;
61 static gint ett_isis_lsp_clv_area_addr = -1;
62 static gint ett_isis_lsp_clv_is_neighbors = -1;
63 static gint ett_isis_lsp_clv_unknown = -1;
64 static gint ett_isis_lsp_clv_partition_dis = -1;
65 static gint ett_isis_lsp_clv_prefix_neighbors = -1;
66 static gint ett_isis_lsp_clv_nlpid = -1;
67 static gint ett_isis_lsp_clv_auth = -1;
68 static gint ett_isis_lsp_clv_ipv4_int_addr = -1;
69 static gint ett_isis_lsp_clv_ip_reachability = -1;
71 static const char *isis_lsp_attached_bits[] = {
72 "error", "expense", "delay", "default" };
74 static const value_string isis_lsp_istype_vals[] = {
75 { ISIS_LSP_TYPE_UNUSED0, "Unused 0x0 (invalid)"},
76 { ISIS_LSP_TYPE_LEVEL_1, "Level 1 IS"},
77 { ISIS_LSP_TYPE_UNUSED2, "Unused 0x2 (invalid)"},
78 { ISIS_LSP_TYPE_LEVEL_2, "Level 2 IS"},
82 * Predclare dissectors for use in clv dissection.
84 static void dissect_lsp_area_address_clv(const u_char *pd, int offset,
85 guint length, int id_length, frame_data *fd, proto_tree *tree);
86 static void dissect_lsp_l1_is_neighbors_clv(const u_char *pd, int offset,
87 guint length, int id_length, frame_data *fd, proto_tree *tree);
88 static void dissect_lsp_l1_es_neighbors_clv(const u_char *pd, int offset,
89 guint length, int id_length, frame_data *fd, proto_tree *tree);
90 static void dissect_lsp_l2_is_neighbors_clv(const u_char *pd, int offset,
91 guint length, int id_length, frame_data *fd, proto_tree *tree);
92 static void dissect_lsp_partition_dis_clv(const u_char *pd, int offset,
93 guint length, int id_length, frame_data *fd, proto_tree *tree);
94 static void dissect_lsp_prefix_neighbors_clv(const u_char *pd, int offset,
95 guint length, int id_length, frame_data *fd, proto_tree *tree);
96 static void dissect_lsp_ip_reachability_clv(const u_char *pd, int offset,
97 guint length, int id_length, frame_data *fd, proto_tree *tree);
98 static void dissect_lsp_nlpid_clv(const u_char *pd, int offset,
99 guint length, int id_length, frame_data *fd, proto_tree *tree);
100 static void dissect_lsp_ip_int_addr_clv(const u_char *pd, int offset,
101 guint length, int id_length, frame_data *fd, proto_tree *tree);
102 static void dissect_lsp_l1_auth_clv(const u_char *pd, int offset,
103 guint length, int id_length, frame_data *fd, proto_tree *tree);
104 static void dissect_lsp_l2_auth_clv(const u_char *pd, int offset,
105 guint length, int id_length, frame_data *fd, proto_tree *tree);
107 static const isis_clv_handle_t clv_l1_lsp_opts[] = {
109 ISIS_CLV_L1_LSP_AREA_ADDRESS,
111 &ett_isis_lsp_clv_area_addr,
112 dissect_lsp_area_address_clv
115 ISIS_CLV_L1_LSP_IS_NEIGHBORS,
117 &ett_isis_lsp_clv_is_neighbors,
118 dissect_lsp_l1_is_neighbors_clv
121 ISIS_CLV_L1_LSP_ES_NEIGHBORS,
123 &ett_isis_lsp_clv_is_neighbors,
124 dissect_lsp_l1_es_neighbors_clv
127 ISIS_CLV_L1_LSP_IP_INT_REACHABLE,
128 "IP Internal reachability",
129 &ett_isis_lsp_clv_ip_reachability,
130 dissect_lsp_ip_reachability_clv
133 ISIS_CLV_L1_LSP_NLPID,
135 &ett_isis_lsp_clv_nlpid,
136 dissect_lsp_nlpid_clv
139 ISIS_CLV_L1_LSP_IP_INTERFACE_ADDR,
140 "IP Interface address(es)",
141 &ett_isis_lsp_clv_ipv4_int_addr,
142 dissect_lsp_ip_int_addr_clv
145 ISIS_CLV_L1_LSP_AUTHENTICATION_NS,
146 "Authentication(non-spec)",
147 &ett_isis_lsp_clv_auth,
148 dissect_lsp_l1_auth_clv
151 ISIS_CLV_L1_LSP_AUTHENTICATION,
153 &ett_isis_lsp_clv_auth,
154 dissect_lsp_l1_auth_clv
164 static const isis_clv_handle_t clv_l2_lsp_opts[] = {
166 ISIS_CLV_L1_LSP_AREA_ADDRESS,
168 &ett_isis_lsp_clv_area_addr,
169 dissect_lsp_area_address_clv
172 ISIS_CLV_L2_LSP_IS_NEIGHBORS,
174 &ett_isis_lsp_clv_is_neighbors,
175 dissect_lsp_l2_is_neighbors_clv
178 ISIS_CLV_L2_LSP_PARTITION_DIS,
179 "Parition Designated Level 2 IS",
180 &ett_isis_lsp_clv_partition_dis,
181 dissect_lsp_partition_dis_clv
184 ISIS_CLV_L2_LSP_PREFIX_NEIGHBORS,
186 &ett_isis_lsp_clv_prefix_neighbors,
187 dissect_lsp_prefix_neighbors_clv
190 ISIS_CLV_L2_LSP_IP_INT_REACHABLE,
191 "IP Internal reachability",
192 &ett_isis_lsp_clv_ip_reachability,
193 dissect_lsp_ip_reachability_clv
196 ISIS_CLV_L2_LSP_NLPID,
198 &ett_isis_lsp_clv_nlpid,
199 dissect_lsp_nlpid_clv
202 ISIS_CLV_L2_LSP_IP_EXT_REACHABLE,
203 "IP external reachability",
204 &ett_isis_lsp_clv_ip_reachability,
205 dissect_lsp_ip_reachability_clv
208 ISIS_CLV_L2_LSP_IP_INTERFACE_ADDR,
209 "IP Interface address(es)",
210 &ett_isis_lsp_clv_ipv4_int_addr,
211 dissect_lsp_ip_int_addr_clv
214 ISIS_CLV_L2_LSP_AUTHENTICATION_NS,
215 "Authentication(non spec)",
216 &ett_isis_lsp_clv_auth,
217 dissect_lsp_l2_auth_clv
220 ISIS_CLV_L2_LSP_AUTHENTICATION,
222 &ett_isis_lsp_clv_auth,
223 dissect_lsp_l2_auth_clv
235 * Name: dissect_metric()
238 * Display a metric prefix portion. ISIS has the concept of multple
239 * metric per prefix (default, delay, expense, and error). This
240 * routine assists other dissectors by adding a single one of
241 * these to the display tree..
243 * The 8th(msbit) bit in the metric octet is the "supported" bit. The
244 * "default" support is required, so we support a "force_supported"
245 * flag that tells us that it MUST be zero (zero==supported,
246 * so it really should be a "not supported" in the boolean sense)
247 * and to display a protocol failure accordingly. Notably,
248 * Cisco IOS 12(6) blows this!
249 * The 7th bit must be zero (reserved).
252 * u_char * : packet data
253 * int : offset into packet data where we are.
254 * guint : length of clv we are decoding
255 * frame_data * : frame data (complete frame)
256 * proto_tree * : protocol display tree to fill out. May be NULL
257 * int : force supported. True is the supported bit MUST be zero.
260 * void, but we will add to proto tree if !NULL.
263 dissect_metric(proto_tree *tree, int offset, guint8 value,
264 char *pstr, int force_supported ) {
269 s = ISIS_LSP_CLV_METRIC_SUPPORTED(value);
270 proto_tree_add_text ( tree, NullTVB, offset, 1,
271 "%s Metric: %s%s %s%d:%d", pstr,
272 s ? "Not supported" : "Supported",
273 (s && force_supported) ? "(but is required to be)":"",
274 ISIS_LSP_CLV_METRIC_RESERVED(value) ? "(reserved bit != 0)":"",
275 ISIS_LSP_CLV_METRIC_VALUE(value), value );
280 * Name: dissect_lsp_ip_reachabillityclv()
283 * Decode an IP reachability CLV. This can be either internal or
284 * external (the clv format does not change and which type we are
285 * displaying is put there by the dispatcher). All of these
286 * are a metric block followed by an IP addr and mask.
289 * u_char * : packet data
290 * int : current offset into packet data
291 * guint : length of this clv
292 * int : length of IDs in packet.
293 * frame_data * : frame data
294 * proto_tree * : proto tree to build on (may be null)
297 * void, will modify proto_tree if not null.
300 dissect_lsp_ip_reachability_clv(const u_char *pd, int offset,
301 guint length, int id_length, frame_data *fd, proto_tree *tree) {
303 proto_tree *ntree = NULL;
306 while ( length > 0 ) {
308 isis_dissect_unknown(offset, length, tree, fd,
309 "short IP reachability (%d vs 12)", length );
313 * Gotta build a sub-tree for all our pieces
316 memcpy(&src, &pd[offset+4], 4);
317 memcpy(&mask, &pd[offset+8], 4);
318 ti = proto_tree_add_text ( tree, NullTVB, offset, 12,
319 "IP prefix: %s (%s) : %s",
320 get_hostname(src), ip_to_str((guint8*)&src),
321 ip_to_str((guint8*)&mask) );
322 ntree = proto_item_add_subtree(ti,
323 ett_isis_lsp_clv_ip_reachability);
324 dissect_metric ( ntree, offset, pd[offset], "Default",
326 dissect_metric ( ntree, offset + 1, pd[offset+1],
328 dissect_metric ( ntree, offset + 2, pd[offset+2],
330 dissect_metric ( ntree, offset + 3, pd[offset+3],
338 * Name: dissect_lsp_nlpid_clv()
341 * Decode for a lsp packets NLPID clv. Calls into the
345 * u_char * : packet data
346 * int : current offset into packet data
347 * guint : length of this clv
348 * int : length of IDs in packet.
349 * frame_data * : frame data
350 * proto_tree * : proto tree to build on (may be null)
353 * void, will modify proto_tree if not null.
356 dissect_lsp_nlpid_clv(const u_char *pd, int offset,
357 guint length, int id_length, frame_data *fd, proto_tree *tree) {
358 isis_dissect_nlpid_clv(pd, offset, length, fd, tree );
362 * Name: dissect_lsp_ip_int_addr_clv()
365 * Decode for a lsp packets ip interface addr clv. Calls into the
369 * u_char * : packet data
370 * int : current offset into packet data
371 * guint : length of this clv
372 * int : length of IDs in packet.
373 * frame_data * : frame data
374 * proto_tree * : proto tree to build on (may be null)
377 * void, will modify proto_tree if not null.
380 dissect_lsp_ip_int_addr_clv(const u_char *pd, int offset,
381 guint length, int id_length, frame_data *fd, proto_tree *tree) {
382 isis_dissect_ip_int_clv(pd, offset, length, fd, tree,
383 hf_isis_lsp_clv_ipv4_int_addr );
387 * Name: dissect_lsp_L1_auth_clv()
390 * Decode for a lsp packets authenticaion clv. Calls into the
391 * clv common one. An auth inside a L1 LSP is a per area password
394 * u_char * : packet data
395 * int : current offset into packet data
396 * guint : length of this clv
397 * int : length of IDs in packet.
398 * frame_data * : frame data
399 * proto_tree * : proto tree to build on (may be null)
402 * void, will modify proto_tree if not null.
405 dissect_lsp_l1_auth_clv(const u_char *pd, int offset,
406 guint length, int id_length, frame_data *fd, proto_tree *tree) {
407 isis_dissect_authentication_clv(pd, offset, length, fd, tree,
408 "Per area authentication" );
412 * Name: dissect_lsp_L2_auth_clv()
415 * Decode for a lsp packets authenticaion clv. Calls into the
416 * clv common one. An auth inside a L2 LSP is a per domain password
419 * u_char * : packet data
420 * int : current offset into packet data
421 * guint : length of this clv
422 * int : length of IDs in packet.
423 * frame_data * : frame data
424 * proto_tree * : proto tree to build on (may be null)
427 * void, will modify proto_tree if not null.
430 dissect_lsp_l2_auth_clv(const u_char *pd, int offset,
431 guint length, int id_length, frame_data *fd, proto_tree *tree) {
432 isis_dissect_authentication_clv(pd, offset, length, fd, tree,
433 "Per domain authentication" );
437 * Name: dissect_lsp_area_address_clv()
440 * Decode for a lsp packet's area address clv. Call into clv common
444 * u_char * : packet data
445 * int : offset into packet data where we are.
446 * guint : length of clv we are decoding
447 * int : length of IDs in packet.
448 * frame_data * : frame data (complete frame)
449 * proto_tree * : protocol display tree to fill out. May be NULL
452 * void, but we will add to proto tree if !NULL.
455 dissect_lsp_area_address_clv(const u_char *pd, int offset,
456 guint length, int id_length, frame_data *fd, proto_tree *tree) {
457 isis_dissect_area_address_clv(pd, offset, length, fd, tree );
461 * Name: dissect_lsp_eis_neighbors_clv_inner()
464 * Real work horse for showing neighbors. This means we decode the
465 * first octet as either virtual/!virtual (if show_virtual param is
466 * set), or as a must == 0 reserved value.
468 * Once past that, we decode n neighbor elements. Each neighbor
469 * is comprised of a metric block (is dissect_metric) and the
473 * u_char * : packet data
474 * int : offset into packet data where we are.
475 * guint : length of clv we are decoding
476 * int : length of IDs in packet.
477 * frame_data * : frame data (complete frame)
478 * proto_tree * : protocol display tree to fill out. May be NULL
479 * int : set to decode first octet as virtual vs reserved == 0
480 * int : set to indicate EIS instead of IS (6 octet per addr instead of 7)
483 * void, but we will add to proto tree if !NULL.
486 dissect_lsp_eis_neighbors_clv_inner(const u_char *pd, int offset,
487 guint length, int id_length, frame_data *fd, proto_tree *tree,
488 int show_virtual, int is_eis) {
490 proto_tree *ntree = NULL;
494 id_length++; /* IDs are one octet longer in IS neighbours */
496 if ( show_virtual ) {
497 /* virtual path flag */
498 proto_tree_add_text ( tree, NullTVB, offset, 1,
499 &pd[offset] ? "IsNotVirtual" : "IsVirtual" );
501 proto_tree_add_text ( tree, NullTVB, offset, 1,
502 "Reserved value 0x%02x, must == 0",
509 tlen = 4 + id_length;
511 while ( length > 0 ) {
513 isis_dissect_unknown(offset, length, tree, fd,
514 "short E/IS reachability (%d vs %d)", length,
519 * Gotta build a sub-tree for all our pieces
523 ti = proto_tree_add_text ( tree, NullTVB, offset, tlen,
525 print_system_id( pd + offset + 4, id_length ) );
527 ti = proto_tree_add_text ( tree, NullTVB, offset, tlen,
529 print_system_id( pd + offset + 4, id_length ) );
531 ntree = proto_item_add_subtree(ti,
532 ett_isis_lsp_clv_is_neighbors);
533 dissect_metric ( ntree, offset, pd[offset], "Default",
535 dissect_metric ( ntree, offset + 1, pd[offset+1],
537 dissect_metric ( ntree, offset + 2, pd[offset+2],
539 dissect_metric ( ntree, offset + 3, pd[offset+3],
541 proto_tree_add_text ( ntree, NullTVB, offset + 4, id_length,
543 print_system_id( pd + offset + 4, id_length ) );
551 * Name: dissect_lsp_l1_is_neighbors_clv()
554 * Dispatch a l1 intermediate system neighbor by calling
555 * the inner function with show virtual set to TRUE and is es set to FALSE.
558 * u_char * : packet data
559 * int : offset into packet data where we are.
560 * guint : length of clv we are decoding
561 * int : length of IDs in packet.
562 * frame_data * : frame data (complete frame)
563 * proto_tree * : protocol display tree to fill out. May be NULL
566 * void, but we will add to proto tree if !NULL.
569 dissect_lsp_l1_is_neighbors_clv(const u_char *pd, int offset,
570 guint length, int id_length, frame_data *fd, proto_tree *tree) {
571 dissect_lsp_eis_neighbors_clv_inner( pd, offset, length, id_length,
572 fd, tree, TRUE, FALSE );
576 * Name: dissect_lsp_l1_es_neighbors_clv()
579 * Dispatch a l1 end or intermediate system neighbor by calling
580 * the inner function with show virtual set to TRUE and es set to TRUE.
583 * u_char * : packet data
584 * int : offset into packet data where we are.
585 * guint : length of clv we are decoding
586 * int : length of IDs in packet.
587 * frame_data * : frame data (complete frame)
588 * proto_tree * : protocol display tree to fill out. May be NULL
591 * void, but we will add to proto tree if !NULL.
594 dissect_lsp_l1_es_neighbors_clv(const u_char *pd, int offset,
595 guint length, int id_length, frame_data *fd, proto_tree *tree) {
596 dissect_lsp_eis_neighbors_clv_inner( pd, offset, length, id_length,
597 fd, tree, TRUE, TRUE);
601 * Name: dissect_lsp_l2_is_neighbors_clv()
604 * Dispatch a l2 intermediate system neighbor by calling
605 * the inner function with show virtual set to FALSE, and is es set
609 * u_char * : packet data
610 * int : offset into packet data where we are.
611 * guint : length of clv we are decoding
612 * int : length of IDs in packet.
613 * frame_data * : frame data (complete frame)
614 * proto_tree * : protocol display tree to fill out. May be NULL
617 * void, but we will add to proto tree if !NULL.
620 dissect_lsp_l2_is_neighbors_clv(const u_char *pd, int offset,
621 guint length, int id_length, frame_data *fd, proto_tree *tree) {
622 dissect_lsp_eis_neighbors_clv_inner(pd, offset, length, id_length,
623 fd, tree, FALSE, FALSE);
627 * Name: dissect_lsp_partition_dis_clv()
630 * This CLV is used to indicate which system is the designated
631 * IS for partition repair. This means just putting out the
632 * "id_length"-octet IS.
635 * u_char * : packet data
636 * int : offset into packet data where we are.
637 * guint : length of clv we are decoding
638 * int : length of IDs in packet.
639 * frame_data * : frame data (complete frame)
640 * proto_tree * : protocol display tree to fill out. May be NULL
643 * void, but we will add to proto tree if !NULL.
646 dissect_lsp_partition_dis_clv(const u_char *pd, int offset,
647 guint length, int id_length, frame_data *fd, proto_tree *tree) {
649 if ( length < id_length ) {
650 isis_dissect_unknown(offset, length, tree, fd,
651 "short lsp parition DIS(%d vs %d)", length,
656 * Gotta build a sub-tree for all our pieces
659 proto_tree_add_text ( tree, NullTVB, offset, id_length,
660 "Partition designated L2 IS: %s",
661 print_system_id( pd + offset, id_length ) );
666 isis_dissect_unknown(offset, length, tree, fd,
667 "Long lsp parition DIS, %d left over", length );
673 * Name: dissect_lsp_prefix_neighbors_clv()
676 * The prefix CLV describes what other (OSI) networks we can reach
677 * and what their cost is. It is built from a metric block
678 * (see dissect_metric) followed by n addresses.
681 * u_char * : packet data
682 * int : offset into packet data where we are.
683 * guint : length of clv we are decoding
684 * int : length of IDs in packet.
685 * frame_data * : frame data (complete frame)
686 * proto_tree * : protocol display tree to fill out. May be NULL
689 * void, but we will add to proto tree if !NULL.
692 dissect_lsp_prefix_neighbors_clv(const u_char *pd, int offset,
693 guint length, int id_length, frame_data *fd, proto_tree *tree) {
698 isis_dissect_unknown(offset, length, tree, fd,
699 "Short lsp prefix neighbors (%d vs 4)", length );
703 dissect_metric ( tree, offset, pd[offset], "Default", TRUE );
704 dissect_metric ( tree, offset + 1, pd[offset+1],
706 dissect_metric ( tree, offset + 2, pd[offset+2],
708 dissect_metric ( tree, offset + 3, pd[offset+3],
713 while ( length > 0 ) {
717 isis_dissect_unknown(offset, length, tree, fd,
718 "Zero payload space after length in prefix neighbor" );
721 if ( mylen > length) {
722 isis_dissect_unknown(offset, length, tree, fd,
723 "Interal length of prefix neighbor too long (%d vs %d)",
729 * Lets turn the area address into "standard" 0000.0000.etc
732 sbuf = print_area( pd + offset + 1, mylen );
733 /* and spit it out */
735 proto_tree_add_text ( tree, NullTVB, offset, mylen + 1,
736 "Area address (%d): %s", mylen, sbuf );
739 length -= mylen; /* length already adjusted for len fld*/
744 * Name: isis_lsp_decode_lsp_id()
747 * Display a LSP id into the display tree.
750 * char * : title string
751 * proto_tree * : tree to display into. REQUIRED
752 * u_char * : packet data
753 * int : offset into packet data where we are.
754 * int : length of IDs in packet.
757 * void, but we will add to proto tree
760 isis_lsp_decode_lsp_id(char *tstr, proto_tree *tree, const u_char *pd,
761 int offset, int id_length ) {
762 proto_tree_add_text(tree, NullTVB, offset, id_length + 2,
763 "%s: %s.%02x-%02x", tstr,
764 print_system_id( pd + offset, id_length ),
765 pd[offset + id_length],
766 pd[offset + id_length + 1] );
770 * Name: isis_dissect_isis_lsp()
773 * Print out the LSP part of the main header and then call the CLV
774 * de-mangler with the right list of valid CLVs.
777 * int : LSP type, a la packet-isis.h ISIS_TYPE_* values
778 * int : header length of packet.
779 * int : length of IDs in packet.
780 * u_char * : packet data
781 * int offset : our offset into packet data.
782 * frame_data * : frame data
783 * proto_tree * : protocol display tree to add to. May be NULL.
786 * void, but we will add to proto tree if !NULL.
789 isis_dissect_isis_lsp(int lsp_type, int header_length, int id_length,
790 const u_char *pd, int offset, frame_data *fd, proto_tree *tree){
792 proto_tree *lsp_tree = NULL;
796 int inx, q, some, value, len;
798 OLD_CHECK_DISPLAY_AS_DATA(proto_isis_lsp, pd, offset, fd, tree);
800 hlen = 2+2+id_length+2+4+2+1;
802 if (!BYTES_ARE_IN_FRAME(offset, hlen)) {
803 isis_dissect_unknown(offset, hlen, tree, fd,
804 "not enough capture data for header (%d vs %d)",
810 ti = proto_tree_add_item(tree, proto_isis_lsp, NullTVB,
811 offset, END_OF_FRAME, FALSE);
812 lsp_tree = proto_item_add_subtree(ti, ett_isis_lsp);
815 pdu_length = pntohs(&pd[offset]);
817 proto_tree_add_uint(lsp_tree, hf_isis_lsp_pdu_length, NullTVB,
818 offset, 2, pdu_length);
823 proto_tree_add_uint(lsp_tree, hf_isis_lsp_remaining_life, NullTVB,
824 offset, 2, pntohs(&pd[offset]));
829 isis_lsp_decode_lsp_id("LSP ID", lsp_tree, pd, offset,
832 offset += id_length + 2;
835 proto_tree_add_uint(lsp_tree, hf_isis_lsp_sequence_number, NullTVB,
837 pntohl(&pd[offset]));
842 /* XXX -> we could validate the cksum here! */
843 proto_tree_add_uint(lsp_tree, hf_isis_lsp_checksum, NullTVB,
844 offset, 2, pntohs(&pd[offset]));
850 * We need to build our type block values.
854 value = ISIS_LSP_ATT(pd[offset]);
856 for ( q = (1<<ISIS_LSP_ATT_SHIFT); q > 0; q = q >> 1 ){
861 strcat ( sbuf, isis_lsp_attached_bits[inx] );
866 strcat ( sbuf, "<none set!>" );
868 proto_tree_add_text(lsp_tree, NullTVB, offset + 18, 1,
869 "Type block(0x%02x): P:%d, Supported metric(s): %s, OL:%d, istype:%s",
871 ISIS_LSP_PARTITION(pd[offset]) ? 1 : 0,
873 ISIS_LSP_HIPPITY(pd[offset]) ? 1 : 0,
874 val_to_str(ISIS_LSP_IS_TYPE(pd[offset]),
875 isis_lsp_istype_vals, "Unknown (0x%x)")
880 len = pdu_length - header_length;
882 isis_dissect_unknown(offset, header_length, tree, fd,
883 "packet header length %d went beyond packet",
888 * Now, we need to decode our CLVs. We need to pass in
889 * our list of valid ones!
891 if (lsp_type == ISIS_TYPE_L1_LSP){
892 isis_dissect_clvs ( clv_l1_lsp_opts, len, id_length, pd,
893 offset, fd, lsp_tree, ett_isis_lsp_clv_unknown );
895 isis_dissect_clvs ( clv_l2_lsp_opts, len, id_length, pd,
896 offset, fd, lsp_tree, ett_isis_lsp_clv_unknown );
900 * Name: proto_register_isis_lsp()
903 * Register our protocol sub-sets with protocol manager.
904 * NOTE: this procedure is autolinked by the makefile process that
908 * u_char * : packet data
909 * int : offset into packet data where we are.
910 * guint : length of clv we are decoding
911 * frame_data * : frame data (complete frame)
912 * proto_tree * : protocol display tree to fill out. May be NULL
915 * void, but we will add to proto tree if !NULL.
918 proto_register_isis_lsp(void) {
919 static hf_register_info hf[] = {
920 { &hf_isis_lsp_pdu_length,
921 { "PDU length", "isis_lsp.pdu_length", FT_UINT16,
922 BASE_DEC, NULL, 0x0, "" }},
924 { &hf_isis_lsp_remaining_life,
925 { "Remaining life", "isis_lsp.remaining_life", FT_UINT16,
926 BASE_DEC, NULL, 0x0, "" }},
928 { &hf_isis_lsp_sequence_number,
929 { "Sequence number", "isis_lsp.sequence_number",
930 FT_UINT32, BASE_HEX, NULL, 0x0, "" }},
932 { &hf_isis_lsp_checksum,
933 { "Checksum", "isis_lsp.checksum",FT_UINT16,
934 BASE_HEX, NULL, 0x0, "" }},
936 { &hf_isis_lsp_clv_ipv4_int_addr,
937 { "IPv4 interface address: ", "isis_lsp.clv_ipv4_int_addr", FT_IPv4,
938 BASE_NONE, NULL, 0x0, "" }},
940 static gint *ett[] = {
942 &ett_isis_lsp_clv_area_addr,
943 &ett_isis_lsp_clv_is_neighbors,
944 &ett_isis_lsp_clv_unknown,
945 &ett_isis_lsp_clv_partition_dis,
946 &ett_isis_lsp_clv_prefix_neighbors,
947 &ett_isis_lsp_clv_auth,
948 &ett_isis_lsp_clv_nlpid,
949 &ett_isis_lsp_clv_ipv4_int_addr,
950 &ett_isis_lsp_clv_ip_reachability,
953 proto_isis_lsp = proto_register_protocol(PROTO_STRING_LSP,
954 "ISIS LSP", "isis_lsp");
955 proto_register_field_array(proto_isis_lsp, hf, array_length(hf));
956 proto_register_subtree_array(ett, array_length(ett));